换个更生活化的接口例子:🍕 披萨订单接口
public interface IPizza
{
string Name { get; set; } // 披萨名称(如"超级至尊")
string Size { get; set; } // 尺寸(大/中/小)
string Crust { get; set; } // 饼底(薄脆/芝心/经典)
string[] Toppings { get; set; } // 配料(芝士/培根/蘑菇等)
string Sauce { get; set; } // 酱料(番茄/奶油/辣味)
bool IsHot { get; set; } // 是否加辣
}
🍽️ 使用示例
// 具体披萨实现
public class SupremePizza : IPizza
{
public string Name { get; set; } = "超级至尊";
public string Size { get; set; } = "大";
public string Crust { get; set; } = "芝心";
public string[] Toppings { get; set; } = new[] { "培根", "香肠", "青椒", "洋葱" };
public string Sauce { get; set; } = "番茄酱";
public bool IsHot { get; set; } = true;
}
// 另一个实现
public class SeafoodPizza : IPizza { /* 实现类似 */ }
🌟 为什么比手机例子更好?
更贴近生活:大家都点过披萨,容易理解各个属性
属性更直观:
Size 替代 Memory(披萨尺寸 vs 手机内存)
Toppings 替代 Camera(配料 vs 摄像头)
可扩展性强:
可以轻松添加新属性(如 ExtraCheese)
配料用数组更符合实际情况
🏭 工厂模式应用
public interface IPizzaFactory
{
IPizza CreatePizza(string type);
}
public class PizzaHutFactory : IPizzaFactory
{
public IPizza CreatePizza(string type)
{
return type switch
{
"Supreme" => new SupremePizza(),
"Seafood" => new SeafoodPizza(),
_ => throw new ArgumentException("不支持的披萨类型")
};
}
}
🆚 对比原手机接口
| 手机接口属性 | 披萨接口对应属性 | 说明 |
|---|---|---|
CPU |
Crust |
核心部分(处理器 vs 饼底) |
Screen |
Size |
最直观的特征 |
Camera |
Toppings |
特色功能(摄像头 vs 配料) |
Battery |
IsHot |
性能表现(续航 vs 辣度) |
这个例子比手机配置参数更生动有趣,也更容易演示工厂模式生产不同产品的过程! 🍕
🍕 披萨建造者接口(修改版)
基于建造者模式,我们可以把披萨的制作过程拆分成多个构建步骤:
public interface IPizzaBuilder
{
IPizza Pizza { get; set; } // 当前制作的披萨
void SelectSize(); // 选择尺寸
void ChooseCrust(); // 选择饼底
void AddSauce(); // 添加酱料
void AddToppings(); // 添加配料
void SetSpiceLevel(); // 设置辣度
IPizza GetPizza(); // 获取制作完成的披萨
}
🏗️ 具体建造者实现(以超级至尊披萨为例)
public class SupremePizzaBuilder : IPizzaBuilder
{
public IPizza Pizza { get; set; } = new Pizza();
public void SelectSize()
{
Pizza.Size = "Large";
}
public void ChooseCrust()
{
Pizza.Crust = "Stuffed Crust";
}
public void AddSauce()
{
Pizza.Sauce = "Tomato Sauce";
}
public void AddToppings()
{
Pizza.Toppings = new[] { "Pepperoni", "Sausage", "Green Peppers", "Onions", "Mushrooms" };
}
public void SetSpiceLevel()
{
Pizza.IsHot = true;
Pizza.SpiceLevel = "Medium";
}
public IPizza GetPizza()
{
Pizza.Name = "Supreme Pizza";
return Pizza;
}
}
👨🍳 主管类(指导建造过程)
public class PizzaChef
{
public IPizza MakePizza(IPizzaBuilder builder)
{
builder.SelectSize();
builder.ChooseCrust();
builder.AddSauce();
builder.AddToppings();
builder.SetSpiceLevel();
return builder.GetPizza();
}
}
🛒 使用示例
// 创建建造者
var pizzaBuilder = new SupremePizzaBuilder();
// 主厨指导制作
var chef = new PizzaChef();
var myPizza = chef.MakePizza(pizzaBuilder);
// 享用披萨
Console.WriteLine($"我的披萨: {myPizza.Name}");
Console.WriteLine($"配料: {string.Join(", ", myPizza.Toppings)}");
🆚 与原建造者接口对比
| 手机建造步骤 | 披萨建造步骤 | 说明 |
|---|---|---|
BuildCPU() |
ChooseCrust() |
核心部件(CPU vs 饼底) |
BuildScreen() |
SelectSize() |
外观特征(屏幕 vs 尺寸) |
BuildCamera() |
AddToppings() |
特色功能(摄像头 vs 配料) |
BuildBattery() |
SetSpiceLevel() |
性能参数(电池 vs 辣度) |
这个建造者模式非常适合披萨制作场景,因为:
披萨制作本来就是分步骤的过程
可以灵活调整每个步骤(如辣度、配料)
可以创建不同风格的建造者(如意大利风格、美式风格)
确保最终产品(披萨)的完整性
🍕 具体建造者实现:海鲜披萨建造者
public class SeafoodPizzaBuilder : IPizzaBuilder
{
public IPizza Pizza { get; set; } = new Pizza();
// 选择大号披萨
public void SelectSize()
{
Pizza.Size = "Large";
Console.WriteLine("选择了大号披萨");
}
// 选择薄脆饼底
public void ChooseCrust()
{
Pizza.Crust = "Thin & Crispy";
Console.WriteLine("选择了薄脆饼底");
}
// 添加白酱(海鲜披萨常用)
public void AddSauce()
{
Pizza.Sauce = "Garlic White Sauce";
Console.WriteLine("添加了蒜香白酱");
}
// 添加丰富的海鲜配料
public void AddToppings()
{
Pizza.Toppings = new[] { "Shrimp", "Squid", "Mussels", "Clams", "Garlic", "Parsley" };
Console.WriteLine("添加了海鲜配料:虾、鱿鱼、青口、蛤蜊");
}
// 设置微辣
public void SetSpiceLevel()
{
Pizza.IsHot = true;
Pizza.SpiceLevel = "Mild";
Console.WriteLine("设置为微辣口味");
}
// 最终完成的海鲜披萨
public IPizza GetPizza()
{
Pizza.Name = "Deluxe Seafood Pizza";
Console.WriteLine("海鲜披萨制作完成!");
return Pizza;
}
}
🦞 使用示例
class Program
{
static void Main(string[] args)
{
// 1. 创建一个海鲜披萨建造者
var seafoodBuilder = new SeafoodPizzaBuilder();
// 2. 主厨指导制作过程
var chef = new PizzaChef();
Console.WriteLine("开始制作海鲜披萨...");
var seafoodPizza = chef.MakePizza(seafoodBuilder);
// 3. 享用披萨
Console.WriteLine("
您点的披萨详情:");
Console.WriteLine($"名称: {seafoodPizza.Name}");
Console.WriteLine($"尺寸: {seafoodPizza.Size}");
Console.WriteLine($"饼底: {seafoodPizza.Crust}");
Console.WriteLine($"酱料: {seafoodPizza.Sauce}");
Console.WriteLine($"配料: {string.Join(", ", seafoodPizza.Toppings)}");
Console.WriteLine($"辣度: {(seafoodPizza.IsHot ? seafoodPizza.SpiceLevel : "不辣")}");
}
}
🖨️ 输出结果示例
开始制作海鲜披萨...
选择了大号披萨
选择了薄脆饼底
添加了蒜香白酱
添加了海鲜配料:虾、鱿鱼、青口、蛤蜊
设置为微辣口味
海鲜披萨制作完成!
您点的披萨详情:
名称: Deluxe Seafood Pizza
尺寸: Large
饼底: Thin & Crispy
酱料: Garlic White Sauce
配料: Shrimp, Squid, Mussels, Clams, Garlic, Parsley
辣度: Mild
🎯 设计要点
分步构建:每个方法只负责一个具体的构建步骤
灵活可变:可以轻松修改某个步骤(如改成”厚饼底”)
统一接口:所有建造者都遵循IPizzaBuilder接口
产品控制:最终通过GetPizza()返回完整产品
这个例子展示了如何为一个具体的海鲜披萨实现建造者模式,每个方法都对应披萨制作的一个实际步骤,最终组合成完整的产品。
🛠️ C#建造者模式通俗讲解(就像组装乐高)
建造者模式就像分步骤组装乐高玩具,把复杂对象的构建过程拆解成多个简单步骤,让组装过程更灵活可控。
🧩 实现过程四步走
1. 准备零件(产品类)
public class Pizza
{
public string Size { get; set; }
public string Crust { get; set; }
public List<string> Toppings { get; set; } = new();
// 其他披萨属性...
}
2. 组装说明书(建造者接口)
public interface IPizzaBuilder
{
void BuildSize(); // 选择尺寸
void BuildCrust(); // 选择饼底
void BuildToppings(); // 添加配料
Pizza GetPizza(); // 获取成品
}
3. 具体组装方案(具体建造者)
public class SpicyPizzaBuilder : IPizzaBuilder
{
private Pizza _pizza = new();
public void BuildSize() => _pizza.Size = "Large";
public void BuildCrust() => _pizza.Crust = "Thin";
public void BuildToppings()
{
_pizza.Toppings.AddRange(new[] { "Pepperoni", "Jalapenos", "Hot Sauce" });
}
public Pizza GetPizza() => _pizza;
}
4. 组装总监(指挥者)
public class PizzaChef
{
public Pizza MakePizza(IPizzaBuilder builder)
{
builder.BuildSize(); // 第一步:选尺寸
builder.BuildCrust(); // 第二步:选饼底
builder.BuildToppings(); // 第三步:加配料
return builder.GetPizza();// 第四步:取成品
}
}
🍽️ 使用示例(像点餐)
// 点一个辣味披萨
var chef = new PizzaChef();
var spicyPizza = chef.MakePizza(new SpicyPizzaBuilder());
// 也可以换其他建造者
var veggiePizza = chef.MakePizza(new VeggiePizzaBuilder());
🌟 模式优势
组装自由:可以通过改变建造者来创建不同产品
步骤可控:指挥者保证建造过程不会遗漏步骤
隐藏细节:用户不需要知道披萨怎么组装的
就像乐高玩具,同样的积木块(建造者接口),按照不同说明书(具体建造者),能组装出完全不同的作品(产品)!
🏗️ 通过抽象类实现建造者模式(完整案例)
建造者模式用抽象类实现,就像定义一个「万能组装说明书」,下面我们以组装电脑为例:
💻 1. 先定义产品(要组装的电脑)
public class Computer
{
public string CPU { get; set; }
public string RAM { get; set; }
public string SSD { get; set; }
public string GPU { get; set; }
public void ShowSpec() =>
Console.WriteLine($"配置:{CPU} + {RAM} + {SSD} + {GPU}");
}
📜 2. 抽象建造者(组装规范)
public abstract class ComputerBuilder
{
protected Computer _computer = new Computer();
// 必须实现的组装步骤(抽象方法)
public abstract void InstallCPU();
public abstract void InstallRAM();
public abstract void InstallSSD();
// 可选步骤(虚方法)
public virtual void InstallGPU() {}
// 获取最终产品
public Computer GetComputer() => _computer;
}
🔧 3. 具体建造者(两种配置方案)
方案一:办公配置
public class OfficeComputerBuilder : ComputerBuilder
{
public override void InstallCPU() =>
_computer.CPU = "Intel i5";
public override void InstallRAM() =>
_computer.RAM = "16GB DDR4";
public override void InstallSSD() =>
_computer.SSD = "512GB NVMe";
// 办公机不需要独立显卡(不重写InstallGPU)
}
方案二:游戏配置
public class GamingComputerBuilder : ComputerBuilder
{
public override void InstallCPU() =>
_computer.CPU = "AMD Ryzen 9";
public override void InstallRAM() =>
_computer.RAM = "32GB DDR5";
public override void InstallSSD() =>
_computer.SSD = "1TB NVMe";
// 游戏机需要显卡
public override void InstallGPU() =>
_computer.GPU = "RTX 4080";
}
🎛️ 4. 指挥者(组装工程师)
public class ComputerEngineer
{
public Computer Build(ComputerBuilder builder)
{
builder.InstallCPU();
builder.InstallRAM();
builder.InstallSSD();
builder.InstallGPU(); // 可选步骤
return builder.GetComputer();
}
}
🛒 5. 使用示例
var engineer = new ComputerEngineer();
// 组装办公机
var officeBuilder = new OfficeComputerBuilder();
var officePC = engineer.Build(officeBuilder);
officePC.ShowSpec(); // 输出:Intel i5 + 16GB DDR4 + 512GB NVMe
// 组装游戏机
var gameBuilder = new GamingComputerBuilder();
var gamePC = engineer.Build(gameBuilder);
gamePC.ShowSpec(); // 输出:AMD Ryzen 9 + 32GB DDR5 + 1TB NVMe + RTX 4080
🌟 抽象类实现的特点
强制与灵活结合:
抽象方法强制必须实现的步骤(CPU/RAM/SSD)
虚方法提供可选步骤(GPU)
代码复用:
公共的GetComputer()方法在抽象类中实现
子类只需要关注具体配置
扩展方便:
新增「服务器配置」只需继承ComputerBuilder
旧代码完全不受影响
就像买组装电脑时:
抽象类是厂商提供的「标准配置单」(必须有哪些部件)
具体建造者是「不同档次的配置方案」
指挥者就是装机小哥,按固定流程帮你组装
🍕 使用抽象类实现披萨建造者模式(完整案例)
下面我们用抽象类来实现一个披萨建造系统,比接口实现更灵活:
1️⃣ 先定义产品(披萨类)
public class Pizza
{
public string Name { get; set; }
public string Size { get; set; }
public string CrustType { get; set; }
public List<string> Toppings { get; } = new List<string>();
public string Sauce { get; set; }
public bool IsSpicy { get; set; }
public void Display()
{
Console.WriteLine($"
🍕 {Name} 披萨");
Console.WriteLine($"尺寸: {Size}");
Console.WriteLine($"饼底: {CrustType}");
Console.WriteLine($"酱料: {Sauce}");
Console.WriteLine($"辣度: {(IsSpicy ? "🌶️ 辣" : "不辣")}");
Console.WriteLine($"配料: {string.Join(", ", Toppings)}");
}
}
2️⃣ 抽象建造者(核心)
public abstract class PizzaBuilder
{
protected Pizza _pizza = new Pizza();
// 必须实现的步骤(抽象方法)
public abstract void SetName();
public abstract void PrepareDough();
public abstract void AddSauce();
public abstract void AddToppings();
// 可选步骤(虚方法)
public virtual void AddSpices() {}
// 钩子方法(子类可覆盖)
public virtual void SetSize() => _pizza.Size = "Medium";
public Pizza GetPizza() => _pizza;
}
3️⃣ 具体建造者实现
意大利风味披萨
public class ItalianPizzaBuilder : PizzaBuilder
{
public override void SetName() => _pizza.Name = "意式经典";
public override void PrepareDough()
{
_pizza.CrustType = "薄脆饼底";
Console.WriteLine("--> 准备意式薄饼底");
}
public override void AddSauce()
{
_pizza.Sauce = "番茄蒜香酱";
Console.WriteLine("--> 涂抹番茄蒜香酱");
}
public override void AddToppings()
{
_pizza.Toppings.AddRange(new[] { "意大利香肠", "橄榄", "蘑菇", "马苏里拉奶酪" });
Console.WriteLine("--> 添加意式配料");
}
public override void SetSize() => _pizza.Size = "Large";
}
美式风味披萨
public class AmericanPizzaBuilder : PizzaBuilder
{
public override void SetName() => _pizza.Name = "美式至尊";
public override void PrepareDough()
{
_pizza.CrustType = "芝心厚饼";
Console.WriteLine("--> 准备美式厚饼底");
}
public override void AddSauce()
{
_pizza.Sauce = "BBQ酱";
Console.WriteLine("--> 涂抹BBQ酱");
}
public override void AddToppings()
{
_pizza.Toppings.AddRange(new[] { "培根", "火腿", "洋葱", "青椒", "双倍奶酪" });
Console.WriteLine("--> 添加美式豪华配料");
}
public override void AddSpices()
{
_pizza.IsSpicy = true;
Console.WriteLine("--> 撒上墨西哥辣椒片");
}
}
4️⃣ 指挥者(披萨师傅)
public class PizzaChef
{
public Pizza MakePizza(PizzaBuilder builder)
{
Console.WriteLine($"
开始制作 {builder.GetType().Name.Replace("Builder","")}...");
builder.SetName();
builder.SetSize(); // 调用钩子方法
builder.PrepareDough();
builder.AddSauce();
builder.AddToppings();
builder.AddSpices(); // 可选步骤
Console.WriteLine("--> 烘烤20分钟");
return builder.GetPizza();
}
}
5️⃣ 使用示例
var chef = new PizzaChef();
// 制作意式披萨
var italianBuilder = new ItalianPizzaBuilder();
var italianPizza = chef.MakePizza(italianBuilder);
italianPizza.Display();
// 制作美式披萨
var americanBuilder = new AmericanPizzaBuilder();
var americanPizza = chef.MakePizza(americanBuilder);
americanPizza.Display();
输出结果示例:
开始制作 ItalianPizza...
--> 准备意式薄饼底
--> 涂抹番茄蒜香酱
--> 添加意式配料
--> 烘烤20分钟
🍕 意式经典 披萨
尺寸: Large
饼底: 薄脆饼底
酱料: 番茄蒜香酱
辣度: 不辣
配料: 意大利香肠, 橄榄, 蘑菇, 马苏里拉奶酪
开始制作 AmericanPizza...
--> 准备美式厚饼底
--> 涂抹BBQ酱
--> 添加美式豪华配料
--> 撒上墨西哥辣椒片
--> 烘烤20分钟
🍕 美式至尊 披萨
尺寸: Medium
饼底: 芝心厚饼
酱料: BBQ酱
辣度: 🌶️ 辣
配料: 培根, 火腿, 洋葱, 青椒, 双倍奶酪
🌟 抽象类实现的优势
灵活控制步骤:
抽象方法强制必须实现的步骤
虚方法提供可选步骤(如AddSpices)
默认实现:
钩子方法SetSize()提供默认中号尺寸,子类可覆盖
日志记录:
每个步骤添加了控制台输出,直观展示建造过程
业务扩展:
很容易新增”素食披萨建造者”等变体
不需要修改现有建造逻辑
🏗️ 建造者模式:乐高积木式创建对象
🧩 什么是建造者模式?
想象你要组装一台电脑:
你不会直接从一堆零件开始胡乱拼装
而是按照说明书(建造者)一步步安装CPU、内存、硬盘
最后得到一台完整电脑
这就是建造者模式的核心思想——分步骤创建复杂对象
🧱 四个核心角色
产品(Product)
👉 最终要组装的完整对象(比如一台电脑/一部手机)
抽象建造者(Builder)
👉 组装说明书(规定有哪些零件要装)
abstract class 电脑组装说明书 {
abstract void 装CPU();
abstract void 装内存();
abstract void 装硬盘();
电脑 获取电脑();
}
具体建造者(ConcreteBuilder)
👉 具体品牌的组装方案
class 游戏电脑组装方案 : 电脑组装说明书 {
void 装CPU() { 装i9处理器(); }
void 装内存() { 装32G内存(); }
//...其他具体实现
}
指挥者(Director)
👉 组装工人(按固定流程组装)
class 装机师傅 {
电脑 组装电脑(电脑组装说明书 说明书) {
说明书.装CPU();
说明书.装内存();
说明书.装硬盘();
return 说明书.获取电脑();
}
}
🎯 为什么用建造者模式?
适用场景:
✔️ 创建的对象很复杂(有很多零件)
✔️ 各零件的组装顺序是固定的
✔️ 同样的组装流程可以产生不同配置的产品
举个栗子🌰:
电脑商城:同样的装机流程,可以装游戏电脑/办公电脑
快餐店:同样的制作流程,可以做汉堡/鸡肉卷
汽车制造:同样的生产线,可以生产SUV/轿车
🔧 具体怎么用?(代码示例)
// 1. 产品:电脑
class 电脑 {
public string CPU { get; set; }
public string 内存 { get; set; }
public string 硬盘 { get; set; }
}
// 2. 抽象建造者
abstract class 电脑建造者 {
protected 电脑 _电脑 = new 电脑();
public abstract void 安装CPU();
public abstract void 安装内存();
public abstract void 安装硬盘();
public 电脑 获取电脑() => _电脑;
}
// 3. 具体建造者:游戏电脑
class 游戏电脑建造者 : 电脑建造者 {
public override void 安装CPU() => _电脑.CPU = "i9-13900K";
public override void 安装内存() => _电脑.内存 = "32GB DDR5";
public override void 安装硬盘() => _电脑.硬盘 = "2TB NVMe SSD";
}
// 4. 指挥者
class 电脑装机员 {
public 电脑 组装电脑(电脑建造者 建造者) {
建造者.安装CPU();
建造者.安装内存();
建造者.安装硬盘();
return 建造者.获取电脑();
}
}
// 使用
var 装机员 = new 电脑装机员();
var 我的电脑 = 装机员.组装电脑(new 游戏电脑建造者());
🌟 模式优点
组装过程标准化:所有电脑都按照相同流程组装
配置灵活多变:同样的流程可以生产不同配置的电脑
隐藏实现细节:用户不需要知道电脑怎么组装的
⚠️ 注意事项
适合零件多且组装顺序固定的场景
如果产品非常简单(只有2-3个零件),可能会显得”杀鸡用牛刀”
不同产品的零件要相似(比如都是电脑零件,不能突然混入汽车零件)
记住这个口诀:
“复杂对象分步造,同样流程不同貌” 🚀


















暂无评论内容