建造者模式:優雅構建復雜對象

引言

在軟件開發中,有時我們需要創建一個由多個部分組成的復雜對象,這些部分可能有不同的變體或配置。如果直接在一個構造函數中設置所有參數,代碼會變得難以閱讀和維護。當對象構建過程復雜,且需要多個步驟時,我們可能會陷入"伸縮式構造函數"的困境,或者創建大量的子類來處理各種組合。

建造者模式(Builder Pattern)提供了一種更優雅的解決方案,它將一個復雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示。這種模式特別適用于需要分步驟創建復雜對象的場景,或者當對象的創建涉及大量參數時。

本文將深入探討建造者模式的概念、實現方式、應用場景以及優缺點,并通過C#代碼示例來展示其實際應用。

文章目錄

    • 引言
    • 建造者模式定義
    • 建造者模式的UML類圖
    • 建造者模式的組成部分
    • 建造者模式的實現方式
      • 基本實現
      • 使用鏈式調用的流暢接口
      • 使用指揮者角色
    • 建造者模式的應用場景
      • 復雜對象的創建
      • 參數眾多的構造函數
      • 不同表示的構建過程
    • 建造者模式的優缺點
      • 優點
      • 缺點
    • 總結
    • 相關學習資源

建造者模式定義

建造者模式(Builder Pattern)的定義是:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示

建造者模式屬于創建型設計模式,它解決的核心問題包括:

  • 如何構建一個由多個部分組成的復雜對象
  • 如何避免"伸縮式構造函數"的問題
  • 如何允許對象有不同的表示形式
  • 如何分離對象的構建和表示

建造者模式的UML類圖

以下是建造者模式的UML類圖:

directs
creates
creates
Director
Construct(builder: Builder)
Builder
BuildPartA()
BuildPartB()
BuildPartC()
GetResult()
ConcreteBuilder1
product: Product
BuildPartA()
BuildPartB()
BuildPartC()
GetResult()
ConcreteBuilder2
product: Product
BuildPartA()
BuildPartB()
BuildPartC()
GetResult()
Product
partA: string
partB: string
partC: string
Show()

建造者模式的組成部分

建造者模式包含以下幾個核心組件:

  1. 產品(Product)

    • 被構建的復雜對象
    • 包含多個組成部分
    • 具體建造者創建該產品的內部表示并定義裝配過程
  2. 抽象建造者(Builder)

    • 聲明創建產品各個部分的抽象接口
    • 定義構建產品各個部分的方法
    • 聲明返回產品的方法
  3. 具體建造者(Concrete Builder)

    • 實現抽象建造者的接口
    • 定義并跟蹤它所創建的產品
    • 提供檢索產品的方法
    • 實現構建產品各個部分的細節
  4. 指揮者(Director)

    • 構造一個使用Builder接口的對象
    • 指導構建過程的順序
    • 隱藏產品是如何組裝的細節

客戶端代碼通常會創建一個具體建造者對象,將其傳遞給指揮者,然后通過指揮者開始構建過程。當構建過程完成后,客戶端從建造者中獲取產品。

建造者模式的實現方式

下面通過C#代碼示例展示建造者模式的幾種實現方式。

基本實現

首先,讓我們看一個食品訂單系統的例子,實現不同類型的餐點組合:

/// <summary>
/// 產品類 - 表示餐點
/// </summary>
public class Meal
{// 餐點的各個組成部分public string MainCourse { get; set; }public string SideDish { get; set; }public string Drink { get; set; }public string Dessert { get; set; }/// <summary>/// 顯示餐點的完整信息/// </summary>public void ShowMeal(){Console.WriteLine("餐點信息:");Console.WriteLine($"- 主菜: {MainCourse ?? "無"}");Console.WriteLine($"- 配菜: {SideDish ?? "無"}");Console.WriteLine($"- 飲料: {Drink ?? "無"}");Console.WriteLine($"- 甜點: {Dessert ?? "無"}");}
}/// <summary>
/// 抽象建造者 - 定義創建餐點各部分的方法
/// </summary>
public interface IMealBuilder
{void BuildMainCourse();void BuildSideDish();void BuildDrink();void BuildDessert();Meal GetMeal();
}/// <summary>
/// 具體建造者 - 健康餐點建造者
/// </summary>
public class HealthyMealBuilder : IMealBuilder
{private Meal _meal = new Meal();public void BuildMainCourse(){_meal.MainCourse = "烤雞胸肉";}public void BuildSideDish(){_meal.SideDish = "蒸蔬菜";}public void BuildDrink(){_meal.Drink = "礦泉水";}public void BuildDessert(){_meal.Dessert = "水果沙拉";}public Meal GetMeal(){return _meal;}
}/// <summary>
/// 具體建造者 - 快餐建造者
/// </summary>
public class FastFoodMealBuilder : IMealBuilder
{private Meal _meal = new Meal();public void BuildMainCourse(){_meal.MainCourse = "漢堡";}public void BuildSideDish(){_meal.SideDish = "炸薯條";}public void BuildDrink(){_meal.Drink = "可樂";}public void BuildDessert(){_meal.Dessert = "冰淇淋";}public Meal GetMeal(){return _meal;}
}/// <summary>
/// 指揮者 - 負責構建過程
/// </summary>
public class MealDirector
{/// <summary>/// 構建完整餐點/// </summary>/// <param name="builder">餐點建造者</param>/// <returns>構建好的餐點</returns>public Meal ConstructFullMeal(IMealBuilder builder){builder.BuildMainCourse();builder.BuildSideDish();builder.BuildDrink();builder.BuildDessert();return builder.GetMeal();}/// <summary>/// 構建沒有甜點的餐點/// </summary>/// <param name="builder">餐點建造者</param>/// <returns>構建好的餐點</returns>public Meal ConstructMealWithoutDessert(IMealBuilder builder){builder.BuildMainCourse();builder.BuildSideDish();builder.BuildDrink();return builder.GetMeal();}
}/// <summary>
/// 客戶端代碼
/// </summary>
public class Client
{public static void Run(){// 創建指揮者var director = new MealDirector();// 使用健康餐點建造者var healthyBuilder = new HealthyMealBuilder();var healthyMeal = director.ConstructFullMeal(healthyBuilder);Console.WriteLine("健康餐點:");healthyMeal.ShowMeal();// 使用快餐建造者,不含甜點var fastFoodBuilder = new FastFoodMealBuilder();var fastFoodMeal = director.ConstructMealWithoutDessert(fastFoodBuilder);Console.WriteLine("\n快餐餐點(無甜點):");fastFoodMeal.ShowMeal();}
}// 執行客戶端代碼
Client.Run();/* 輸出結果:
健康餐點:
餐點信息:
- 主菜: 烤雞胸肉
- 配菜: 蒸蔬菜
- 飲料: 礦泉水
- 甜點: 水果沙拉快餐餐點(無甜點):
餐點信息:
- 主菜: 漢堡
- 配菜: 炸薯條
- 飲料: 可樂
- 甜點: 無
*/

在這個基本實現中:

  • Meal 是被構建的產品
  • IMealBuilder 是抽象建造者,定義了構建餐點各部分的方法
  • HealthyMealBuilderFastFoodMealBuilder 是具體建造者,實現了不同風格的餐點創建
  • MealDirector 是指揮者,控制構建過程的順序
  • 客戶端可以選擇不同的建造者來創建不同類型的餐點,以及選擇不同的構建方式(完整或無甜點)

使用鏈式調用的流暢接口

建造者模式的一個常見變體是使用方法鏈(鏈式調用)創建流暢接口,這在C#中特別常見:

/// <summary>
/// 產品類 - 電子郵件
/// </summary>
public class Email
{// 電子郵件的各個組成部分public string From { get; set; }public string To { get; set; }public string Subject { get; set; }public string Body { get; set; }public List<string> Attachments { get; set; } = new List<string>();public bool IsHtml { get; set; }public string Cc { get; set; }public string Bcc { get; set; }/// <summary>/// 顯示電子郵件的內容/// </summary>public void Display(){Console.WriteLine("電子郵件詳情:");Console.WriteLine($"發件人: {From}");Console.WriteLine($"收件人: {To}");if (!string.IsNullOrEmpty(Cc)) Console.WriteLine($"抄送: {Cc}");if (!string.IsNullOrEmpty(Bcc)) Console.WriteLine($"密送: {Bcc}");Console.WriteLine($"主題: {Subject}");Console.WriteLine($"正文: {Body}");Console.WriteLine($"格式: {(IsHtml ? "HTML" : "純文本")}");if (Attachments.Count > 0){Console.WriteLine("附件:");foreach (var attachment in Attachments){Console.WriteLine($"- {attachment}");}}}
}/// <summary>
/// 流暢接口建造者 - 電子郵件建造者
/// </summary>
public class EmailBuilder
{private readonly Email _email = new Email();/// <summary>/// 設置發件人地址/// </summary>/// <param name="from">發件人郵箱地址</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder From(string from){_email.From = from;return this;}/// <summary>/// 設置收件人地址/// </summary>/// <param name="to">收件人郵箱地址</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder To(string to){_email.To = to;return this;}/// <summary>/// 設置郵件主題/// </summary>/// <param name="subject">郵件主題</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder WithSubject(string subject){_email.Subject = subject;return this;}/// <summary>/// 設置郵件正文內容/// </summary>/// <param name="body">郵件內容</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder WithBody(string body){_email.Body = body;return this;}/// <summary>/// 添加附件/// </summary>/// <param name="attachment">附件路徑</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder WithAttachment(string attachment){_email.Attachments.Add(attachment);return this;}/// <summary>/// 設置郵件為HTML格式/// </summary>/// <param name="isHtml">是否是HTML格式</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder AsHtml(bool isHtml = true){_email.IsHtml = isHtml;return this;}/// <summary>/// 設置抄送地址/// </summary>/// <param name="cc">抄送郵箱地址</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder WithCc(string cc){_email.Cc = cc;return this;}/// <summary>/// 設置密送地址/// </summary>/// <param name="bcc">密送郵箱地址</param>/// <returns>當前建造者實例以支持鏈式調用</returns>public EmailBuilder WithBcc(string bcc){_email.Bcc = bcc;return this;}/// <summary>/// 構建電子郵件對象/// </summary>/// <returns>構建好的電子郵件</returns>public Email Build(){// 這里可以添加驗證邏輯,例如檢查必填字段if (string.IsNullOrEmpty(_email.From))throw new InvalidOperationException("發件人地址不能為空");if (string.IsNullOrEmpty(_email.To))throw new InvalidOperationException("收件人地址不能為空");return _email;}
}// 客戶端代碼
public class FluentClient
{public static void Run(){// 使用流暢接口創建一封簡單郵件var simpleEmail = new EmailBuilder().From("sender@example.com").To("recipient@example.com").WithSubject("問候郵件").WithBody("您好!這是一封測試郵件。").Build();Console.WriteLine("簡單郵件:");simpleEmail.Display();// 使用流暢接口創建一封復雜郵件var complexEmail = new EmailBuilder().From("manager@company.com").To("team@company.com").WithCc("supervisor@company.com").WithBcc("records@company.com").WithSubject("項目進度報告").WithBody("<h1>項目進度</h1><p>團隊成員們,請查看附件中的項目進度報告。</p>").AsHtml().WithAttachment("progress_report.pdf").WithAttachment("schedule.xlsx").Build();Console.WriteLine("\n復雜郵件:");complexEmail.Display();}
}// 執行客戶端代碼
FluentClient.Run();/* 輸出結果:
簡單郵件:
電子郵件詳情:
發件人: sender@example.com
收件人: recipient@example.com
主題: 問候郵件
正文: 您好!這是一封測試郵件。
格式: 純文本復雜郵件:
電子郵件詳情:
發件人: manager@company.com
收件人: team@company.com
抄送: supervisor@company.com
密送: records@company.com
主題: 項目進度報告
正文: <h1>項目進度</h1><p>團隊成員們,請查看附件中的項目進度報告。</p>
格式: HTML
附件:
- progress_report.pdf
- schedule.xlsx
*/

在這個流暢接口實現中:

  • 每個設置方法返回建造者本身,這使得可以鏈式調用方法
  • 提供了一種更加簡潔、可讀性更高的方式來構建復雜對象
  • 允許按需設置各個屬性,支持可選參數
  • 在最后調用Build()方法來獲取構建好的對象,同時可以進行必要的驗證

使用指揮者角色

在一些更復雜的場景中,指揮者(Director)角色可以更好地封裝不同的構建過程。下面是一個使用指揮者角色的計算機配置示例:

/// <summary>
/// 產品類 - 計算機
/// </summary>
public class Computer
{// 計算機的各個組件public string CPU { get; set; }public string RAM { get; set; }public string Storage { get; set; }public string GraphicsCard { get; set; }public string Monitor { get; set; }public string OperatingSystem { get; set; }/// <summary>/// 顯示計算機配置/// </summary>public void ShowConfiguration(){Console.WriteLine("計算機配置:");Console.WriteLine($"CPU: {CPU ?? "未指定"}");Console.WriteLine($"內存: {RAM ?? "未指定"}");Console.WriteLine($"存儲: {Storage ?? "未指定"}");Console.WriteLine($"顯卡: {GraphicsCard ?? "未指定"}");Console.WriteLine($"顯示器: {Monitor ?? "未指定"}");Console.WriteLine($"操作系統: {OperatingSystem ?? "未指定"}");}
}/// <summary>
/// 抽象建造者 - 計算機建造者
/// </summary>
public interface IComputerBuilder
{void BuildCPU();void BuildRAM();void BuildStorage();void BuildGraphicsCard();void BuildMonitor();void InstallOperatingSystem();Computer GetComputer();
}/// <summary>
/// 具體建造者 - 游戲計算機建造者
/// </summary>
public class GamingComputerBuilder : IComputerBuilder
{private Computer _computer = new Computer();public void BuildCPU(){_computer.CPU = "Intel Core i9-11900K";}public void BuildRAM(){_computer.RAM = "32GB DDR4 3600MHz";}public void BuildStorage(){_computer.Storage = "2TB NVMe SSD";}public void BuildGraphicsCard(){_computer.GraphicsCard = "NVIDIA GeForce RTX 3080";}public void BuildMonitor(){_computer.Monitor = "27英寸 4K 144Hz 游戲顯示器";}public void InstallOperatingSystem(){_computer.OperatingSystem = "Windows 11 Pro";}public Computer GetComputer(){return _computer;}
}/// <summary>
/// 具體建造者 - 辦公計算機建造者
/// </summary>
public class OfficeComputerBuilder : IComputerBuilder
{private Computer _computer = new Computer();public void BuildCPU(){_computer.CPU = "Intel Core i5-11400";}public void BuildRAM(){_computer.RAM = "16GB DDR4 2666MHz";}public void BuildStorage(){_computer.Storage = "512GB SSD";}public void BuildGraphicsCard(){_computer.GraphicsCard = "集成顯卡";}public void BuildMonitor(){_computer.Monitor = "24英寸 1080p 辦公顯示器";}public void InstallOperatingSystem(){_computer.OperatingSystem = "Windows 10 專業版";}public Computer GetComputer(){return _computer;}
}/// <summary>
/// 具體建造者 - 開發計算機建造者
/// </summary>
public class DeveloperComputerBuilder : IComputerBuilder
{private Computer _computer = new Computer();public void BuildCPU(){_computer.CPU = "AMD Ryzen 9 5900X";}public void BuildRAM(){_computer.RAM = "64GB DDR4 3200MHz";}public void BuildStorage(){_computer.Storage = "1TB NVMe SSD + 2TB HDD";}public void BuildGraphicsCard(){_computer.GraphicsCard = "NVIDIA GeForce RTX 3060";}public void BuildMonitor(){_computer.Monitor = "雙 27英寸 4K 專業顯示器";}public void InstallOperatingSystem(){_computer.OperatingSystem = "Ubuntu 22.04 LTS";}public Computer GetComputer(){return _computer;}
}/// <summary>
/// 指揮者 - 計算機裝配指揮者
/// </summary>
public class ComputerDirector
{/// <summary>/// 構建完整計算機/// </summary>/// <param name="builder">計算機建造者</param>/// <returns>構建好的計算機</returns>public Computer BuildFullComputer(IComputerBuilder builder){builder.BuildCPU();builder.BuildRAM();builder.BuildStorage();builder.BuildGraphicsCard();builder.BuildMonitor();builder.InstallOperatingSystem();return builder.GetComputer();}/// <summary>/// 構建基本計算機(無顯卡、基本顯示器)/// </summary>/// <param name="builder">計算機建造者</param>/// <returns>構建好的計算機</returns>public Computer BuildBasicComputer(IComputerBuilder builder){builder.BuildCPU();builder.BuildRAM();builder.BuildStorage();builder.InstallOperatingSystem();return builder.GetComputer();}/// <summary>/// 構建無操作系統的計算機/// </summary>/// <param name="builder">計算機建造者</param>/// <returns>構建好的計算機</returns>public Computer BuildComputerWithoutOS(IComputerBuilder builder){builder.BuildCPU();builder.BuildRAM();builder.BuildStorage();builder.BuildGraphicsCard();builder.BuildMonitor();return builder.GetComputer();}
}/// <summary>
/// 客戶端代碼
/// </summary>
public class DirectorClient
{public static void Run(){// 創建指揮者var director = new ComputerDirector();// 構建游戲計算機(完整配置)var gamingBuilder = new GamingComputerBuilder();var gamingComputer = director.BuildFullComputer(gamingBuilder);Console.WriteLine("游戲計算機配置:");gamingComputer.ShowConfiguration();// 構建基本辦公計算機var officeBuilder = new OfficeComputerBuilder();var officeComputer = director.BuildBasicComputer(officeBuilder);Console.WriteLine("\n辦公計算機配置:");officeComputer.ShowConfiguration();// 構建無操作系統的開發計算機var developerBuilder = new DeveloperComputerBuilder();var developerComputer = director.BuildComputerWithoutOS(developerBuilder);Console.WriteLine("\n開發計算機配置(無操作系統):");developerComputer.ShowConfiguration();}
}// 執行客戶端代碼
DirectorClient.Run();/* 輸出結果:
游戲計算機配置:
計算機配置:
CPU: Intel Core i9-11900K
內存: 32GB DDR4 3600MHz
存儲: 2TB NVMe SSD
顯卡: NVIDIA GeForce RTX 3080
顯示器: 27英寸 4K 144Hz 游戲顯示器
操作系統: Windows 11 Pro辦公計算機配置:
計算機配置:
CPU: Intel Core i5-11400
內存: 16GB DDR4 2666MHz
存儲: 512GB SSD
顯卡: 未指定
顯示器: 未指定
操作系統: Windows 10 專業版開發計算機配置(無操作系統):
計算機配置:
CPU: AMD Ryzen 9 5900X
內存: 64GB DDR4 3200MHz
存儲: 1TB NVMe SSD + 2TB HDD
顯卡: NVIDIA GeForce RTX 3060
顯示器: 雙 27英寸 4K 專業顯示器
操作系統: 未指定
*/

在這個實現中:

  • 指揮者(ComputerDirector)定義了多種不同的構建過程(完整、基本、無操作系統)
  • 具體建造者(GamingComputerBuilderOfficeComputerBuilderDeveloperComputerBuilder)提供了不同的實現方式
  • 客戶端可以選擇不同的建造者和構建過程的組合,以獲得不同配置的計算機
  • 指揮者封裝了構建過程,使得客戶端代碼更加簡潔

建造者模式的應用場景

建造者模式適用于以下場景:

建造者模式應用場景
復雜對象的創建
參數眾多的構造函數
不同表示的構建過程
分步構建對象
不變性對象的創建

復雜對象的創建

當對象包含多個部分,或者構建需要多個步驟時,建造者模式能夠提供清晰的創建過程:

  • 文檔生成器(如HTML、PDF、Word文檔)
  • 復雜的圖形用戶界面構建
  • 配置對象的創建
  • 復雜的數據轉換和導出

參數眾多的構造函數

在需要處理大量可選參數時,建造者模式可以避免"伸縮式構造函數"問題:

  • 避免了使用多個重載構造函數
  • 避免了使用大量參數的構造函數
  • 允許僅設置需要的參數
  • 代碼可讀性和可維護性更高

不同表示的構建過程

當同一個構建過程可以創建不同表示的對象時,建造者模式特別有用:

  • 不同格式的報告生成
  • 不同風格的UI組件創建
  • 不同平臺的代碼生成器

建造者模式的優缺點

優點

  1. 分離構建和表示:建造者模式將對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示。

  2. 封裝變化:產品的內部結構可以變化,而不會影響客戶端代碼,因為客戶端只與抽象接口交互。

  3. 更好的控制構建過程:建造者模式允許對對象的構建過程進行更精細的控制,特別是在復雜對象的構建中。

  4. 隱藏產品的內部結構:產品的具體細節對客戶端是不可見的,客戶端只需要與建造者交互。

  5. 提高代碼可讀性:特別是在使用流暢接口時,構建過程清晰易讀。

缺點

  1. 增加類的數量:建造者模式引入了多個新的類,這可能增加系統的復雜性。

  2. 與特定類型綁定:每個具體建造者與特定的產品類型綁定,限制了靈活性。

  3. 不適合簡單對象:對于簡單對象,使用建造者模式可能是過度設計。

  4. 指揮者可能不總是必要的:在一些實現中,特別是使用流暢接口時,指揮者角色可能是多余的。

  5. 可能導致代碼重復:不同的具體建造者可能包含相似的代碼。

總結

建造者模式是一種功能強大的創建型設計模式,它允許我們分步驟創建復雜對象,并且可以使用相同的構建過程創建不同的表示。這種模式特別適合處理具有多個組成部分或需要復雜構建過程的對象。

在C#中,建造者模式有多種實現方式,從傳統的實現(使用抽象建造者、具體建造者和指揮者),到更現代的流暢接口實現。流暢接口特別適合C#,它提供了一種簡潔、可讀性強的方式來構建對象。

建造者模式與其他創建型模式(如工廠方法和抽象工廠)相比,更加關注對象的分步構建過程,而不僅僅是簡單的實例化。它為控制復雜對象的創建過程提供了更細粒度的方法。

雖然建造者模式增加了代碼的復雜性,但在處理復雜對象創建、避免構造函數參數過多或需要不同表示的場景中,這種復雜性是值得的。通過合理應用建造者模式,我們可以創建更加靈活、可維護和可擴展的代碼。

相關學習資源

網站資源:

  • Refactoring Guru - Builder Pattern
  • Microsoft Learn - Design Patterns
  • SourceMaking - Builder Design Pattern
  • C# Corner - Builder Design Pattern in C#
  • Dofactory - .NET Design Pattern Framework - Builder

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908107.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908107.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908107.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何通過akshare庫,獲取股票數據,并生成TabPFN這個模型 可以識別、處理的格式(并進行了訓練、推理)

計劃讓AI幫助編程使用TabPFN模型進行股價推理 原計劃提問的prompt 如何通過akshare庫&#xff0c;獲取股票數據&#xff0c;并生成TabPFN這個模型 可以識別、處理的格式 本意是想讓AI分步執行&#xff0c;先處理股票數據&#xff0c;然后再進行模型訓練&#xff0c;結果豆包超…

[藍橋杯]最大化股票交易的利潤

最大化股票交易的利潤 題目描述 實現一個算法尋找最大化股票交易利潤的策略。介紹如下&#xff1a; 股票價格每天都在變化&#xff0c;以數組的索引表示交易日&#xff0c;以數組的元素表示每天的股票價格。可以通過買入和賣出獲得利潤。一天只能進行一次買入或賣出操作&…

URL 結構說明+路由(接口)的認識

一、URL 結構說明 以這個為例&#xff1a;http://127.0.0.1:5000/zhouleifeng 1.組成部分: http://&#xff1a;協議 127.0.0.1&#xff1a;主機&#xff08;本地地址&#xff09; :5000&#xff1a;端口號&#xff08;Flask 默認 5000&#xff09; /zhouleifeng&#xff1a…

微服務商城-用戶微服務

數據表 用戶表 CREATE DATABASE user; USE user;CREATE TABLE user (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 用戶ID,username varchar(50) NOT NULL DEFAULT COMMENT 用戶名,password varchar(50) NOT NULL DEFAULT COMMENT 用戶密碼&#xff0c;MD5加密…

Java面試題及答案整理( 2025年最新版,持續更新...)

最近發現網上很多Java面試題都沒有答案&#xff0c;所以花了很長時間搜集整理出來了這套Java面試題大全&#xff0c;希望大家能夠喜歡&#xff01; 注&#xff1a;篇幅有限&#xff0c;資料已整理成文檔&#xff0c;后臺si我666&#xff0c;我一個個發&#xff01; 這套面試文…

[論文閱讀]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning

PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning | IJCAI IJCAI-22 發表于2022年的論文&#xff0c;當時大家還都在做小模型NLP的相關工作&#xff08;BERT&#xff0c;Ro…

Redis最佳實踐——性能優化技巧之集群與分片

Redis集群與分片在電商應用中的性能優化技巧 一、Redis集群架構模式解析 1. 主流集群方案對比 方案核心原理適用場景電商應用案例主從復制讀寫分離數據冗余中小規模讀多寫少商品詳情緩存Redis Sentinel自動故障轉移監控高可用需求場景訂單狀態緩存Redis Cluster原生分布式分片…

Vue 生命周期全解析:從創建到銷毀的完整旅程

Vue 生命周期是每個 Vue 開發者必須深入理解的核心概念之一。它定義了組件從創建、掛載、更新、銷毀的整個過程&#xff0c;以及在這個過程中各個階段提供的鉤子函數。掌握生命周期不僅能幫助你理解 Vue 的工作原理&#xff0c;還能讓你在合適的時機執行特定的操作&#xff0c;…

【Rust 高級trait】Rust trait的一些高級用法解密

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

聯想電腦護眼衛士與系統顏色配置(X-Rite)沖突 | 顯示設置頻繁變換色階 - 解決方案

聯想電腦護眼衛士與系統顏色配置X-Rite沖突 | 顯示設置頻繁變換色階 - 解決方案 前言方案1&#xff1a;解決聯想護眼衛士方案2&#xff1a;解決系統顏色配置(X-Rite) 前言 自帶X-Rite軟件的聯想電腦&#xff08;以拯救者Y9000P&#xff0c;Win11系統為例&#xff09;&#xff…

MySQL中SELECT查詢的執行順序

MySQL中SELECT查詢的執行順序 在日常的數據庫開發中&#xff0c;我們經常會寫各種復雜的SELECT查詢語句。然而&#xff0c;很多開發者對于MySQL實際執行這些查詢的順序并不完全了解。理解查詢的執行順序不僅有助于編寫更高效的SQL語句&#xff0c;還能幫助我們更好地優化查詢性…

es 的字段類型(text和keyword)

Text 當一個字段是要被全文檢索時&#xff0c;比如 Email 內容、產品描述&#xff0c;這些字段應該使用 text 類型。設置 text 類型以后&#xff0c;字段內容會被分析&#xff0c;在生成倒排索引之前&#xff0c;字符串會被分析器分詞。text類型的字段不用于排序&#xff0c;很…

MySQL安裝及啟用詳細教程(Windows版)

MySQL安裝及啟用詳細教程&#xff08;Windows版&#xff09; &#x1f4cb; 概述 本文檔將詳細介紹MySQL數據庫在Windows系統下的下載、安裝、配置和啟用過程。 &#x1f4e5; MySQL下載 官方下載地址 官方網站: https://dev.mysql.com/downloads/社區版本: https://dev.my…

Linux下使用nmcli連接網絡

Linux下使用nmcli連接網絡 介紹 在使用ubuntu系統的時候&#xff0c;有時候不方便使用桌面&#xff0c;使用ssh遠程連接&#xff0c;可能需要使用nmcli命令來連接網絡。本文將介紹如何使用nmcli命令連接網絡。nmcli 是 NetworkManager 的命令行工具&#xff0c;用于管理網絡連…

Python----循環神經網絡(BiLSTM:雙向長短時記憶網絡)

一、LSTM 與 BiLSTM對比 1.1、LSTM LSTM&#xff08;長短期記憶網絡&#xff09; 是一種改進的循環神經網絡&#xff08;RNN&#xff09;&#xff0c;專門解決傳統RNN難以學習長期依賴的問題。它通過遺忘門、輸入門和輸出門來控制信息的流動&#xff0c;保留重要信息并丟棄無關…

U盤掛載Linux

在 只能使用 Telnet 的情況下&#xff0c;如果希望通過 U盤 傳輸文件到 Linux 系統&#xff0c;可以按照以下步驟操作&#xff1a; &#x1f4cc; 前提條件 U盤已插入 Linux 主機的 USB 接口。Linux 主機支持自動掛載 U盤&#xff08;大多數現代發行版默認支持&#xff09;。T…

QuickBASIC QB64 支持 64 位系統和跨平臺Linux/MAC OS

QuickBASIC 的現代繼任者 QB64 已發展成為一個功能強大的開源項目&#xff0c;支持 64 位系統和跨平臺開發。以下是詳細介紹&#xff1a; 項目首頁 - QB64pe:The QB64 Phoenix Edition Repository - GitCode https://gitcode.com/gh_mirrors/qb/QB64pe 1. QB64 概述 官網&am…

【C++高級主題】命令空間(五):類、命名空間和作用域

目錄 一、實參相關的查找&#xff08;ADL&#xff09;&#xff1a;函數調用的 “智能搜索” 1.1 ADL 的核心規則 1.2 ADL 的觸發條件 1.3 ADL 的典型應用場景 1.4 ADL 的潛在風險與規避 二、隱式友元聲明&#xff1a;類與命名空間的 “私密通道” 2.1 友元聲明的基本規則…

免費開源Umi-OCR,離線使用,批量精準!

Umi-OCR&#xff08;Windows端&#xff09; Umi-OCR 是一款在 GitHub 上開源的免費 OCR 識別軟件&#xff0c;它最大的亮點就是免費、開源、支持批量處理&#xff0c;而且識別準確度很高。這款軟件不需要聯網就能用&#xff0c;非常值得推薦&#xff01; 在 OCR 識別功能方面&…

深入剖析 Docker 容器化原理與實戰應用,開啟技術新征程!

文章目錄 前言一、為什么 是Docker &#xff1f;二、Docker 容器化原理分析2.1 鏡像&#xff08;Image&#xff09;2.2 容器&#xff08;Container&#xff09;2.3 倉庫&#xff08;Registry&#xff09; 三、Docker 容器化實踐3.1 Docker安裝3.2 創建一個 Docker 鏡像3.3 運行…