用C#模板方法模式开发设计,代码复用率提升300%
|
admin
2026年1月23日 12:0
本文热度 112
|
引言
想象一下,你在咖啡店打工,每天要做美式、拿铁、卡布奇诺等不同咖啡。虽然种类不同,但制作流程相似:磨豆 → 萃取 → 添加配料 → 装饰 → 交给顾客。
聪明的店长会给你一张"通用咖啡制作流程卡",上面写好固定步骤,只把需要调整的部分(比如加什么配料)空出来让你填。
在编程中,模板方法模式就像这张"流程卡",帮我们解决重复代码的问题。当多个功能有相同流程、只有少数步骤不同时,它能让代码更简洁、更好维护。
什么是模板方法模式?
核心思想
模板方法模式的核心:把通用流程固定,让具体细节由子类实现。
比如做咖啡的流程是固定的,但添加什么配料(牛奶、奶泡或什么都不加)则因咖啡类型而异。
在编程中,它的工作方式是:
模式结构
模板方法模式的结构就像"流程卡":
| |
|---|
| 抽象类 | |
| 具体子类 | |
| 模板方法 | |
| 基本方法 | 包括:抽象方法(必须实现)、具体方法(通用步骤)、钩子方法(可选覆盖) |
记忆口诀
流程我来定,细节你去填,顺序不能变,省力又省钱
C# 实战:制作你的咖啡系统
让我们通过一个咖啡制作系统来体验模板方法模式的魅力,支持美式、拿铁和卡布奇诺的制作。
1. 咖啡制作流程模板
public abstract class CoffeeMaker
{
// 模板方法:咖啡制作的核心流程
public void MakeCoffee()
{
Console.WriteLine("=== 开始制作咖啡 ===");
GrindCoffeeBeans(); // 1. 磨咖啡豆(通用步骤)
BrewCoffee(); // 2. 萃取咖啡(通用步骤)
AddCondiments(); // 3. 添加配料(由子类实现)
DecorateCoffee(); // 4. 装饰咖啡(可选择覆盖)
ServeCoffee(); // 5. 服务咖啡(通用步骤)
Console.WriteLine("=== 咖啡制作完成 ===\n");
}
// 具体方法:所有咖啡都需要的通用步骤
private void GrindCoffeeBeans()
{
Console.WriteLine("1. 磨咖啡豆");
Console.WriteLine(" - 选择中度研磨");
Console.WriteLine(" - 研磨 10 秒");
}
private void BrewCoffee()
{
Console.WriteLine("2. 萃取咖啡");
Console.WriteLine(" - 注入 92°C 热水");
Console.WriteLine(" - 萃取 25 秒");
}
// 抽象方法:子类必须实现的步骤
protected abstract void AddCondiments();
// 钩子方法:子类可以选择是否覆盖
protected virtual void DecorateCoffee()
{
Console.WriteLine("4. 装饰咖啡");
Console.WriteLine(" - 撒上少量可可粉");
}
private void ServeCoffee()
{
Console.WriteLine("5. 服务咖啡");
Console.WriteLine(" - 放入杯垫");
Console.WriteLine(" - 交给顾客");
}
}
2. 具体咖啡制作器
// 美式咖啡制作器:简单纯粹
public class AmericanoMaker : CoffeeMaker
{
protected override void AddCondiments()
{
Console.WriteLine("3. 添加配料");
Console.WriteLine(" - 美式咖啡:什么都不加,保持纯粹");
}
protected override void DecorateCoffee()
{
Console.WriteLine("4. 装饰咖啡");
Console.WriteLine(" - 美式咖啡:不需要装饰");
}
}
// 拿铁咖啡制作器:牛奶爱好者
public class LatteMaker : CoffeeMaker
{
protected override void AddCondiments()
{
Console.WriteLine("3. 添加配料");
Console.WriteLine(" - 拿铁咖啡:添加蒸牛奶");
Console.WriteLine(" - 牛奶与咖啡比例 1:1");
}
protected override void DecorateCoffee()
{
Console.WriteLine("4. 装饰咖啡");
Console.WriteLine(" - 拿铁咖啡:拉花");
Console.WriteLine(" - 画出心形图案");
}
}
// 卡布奇诺制作器:奶泡控
public class CappuccinoMaker : CoffeeMaker
{
protected override void AddCondiments()
{
Console.WriteLine("3. 添加配料");
Console.WriteLine(" - 卡布奇诺:添加奶泡");
Console.WriteLine(" - 奶泡与咖啡比例 1:1");
}
// 这里没有覆盖 DecorateCoffee 方法,使用父类默认实现
}
3. 测试咖啡制作系统
class Program
{
static void Main(string[] args)
{
Console.WriteLine("欢迎来到咖啡店!\n");
// 制作美式咖啡
Console.WriteLine("顾客点了:美式咖啡");
CoffeeMaker americanoMaker = new AmericanoMaker();
americanoMaker.MakeCoffee();
// 制作拿铁咖啡
Console.WriteLine("顾客点了:拿铁咖啡");
CoffeeMaker latteMaker = new LatteMaker();
latteMaker.MakeCoffee();
// 制作卡布奇诺
Console.WriteLine("顾客点了:卡布奇诺");
CoffeeMaker cappuccinoMaker = new CappuccinoMaker();
cappuccinoMaker.MakeCoffee();
Console.WriteLine("咖啡制作系统测试完成!");
}
}
4. 运行结果如下:
分析
- • 钩子灵活:美式和拿铁覆盖装饰方法,卡布奇诺使用默认实现
核心优势:流程由父类控制,细节由子类实现。
模板方法模式的优缺点
优点
- 1. 代码复用:公共代码只写一次,减少重复,提高开发效率。
- 3. 扩展性好:添加新功能只需创建子类,无需修改现有代码。
- 4. 控制流程:父类控制流程顺序,子类专注实现细节。
缺点
- 1. 灵活性有限:流程固定,子类不能改变步骤顺序。
- 2. 类层次可能变复杂:实现过多时,子类数量增加。
适用场景
模板方法模式适用于:
- 1. 流程固定,细节不同:如不同咖啡的制作、不同支付方式的处理。
- 2. 需要统一管理流程:如公司请假流程、软件安装向导。
- 3. 代码重复较多:多个类有大量重复代码,只有少数部分不同。
代码优化建议
- 1. 只抽象必要的步骤:仅将需要子类实现的步骤定义为抽象方法。
- 2. 合理使用钩子方法:对于可选步骤,使用虚方法让子类选择是否覆盖。
- 3. 保持模板方法简洁:模板方法只定义流程,不包含具体业务逻辑。
- 4. 遵循里氏替换原则:确保子类实现能正确替换父类位置。
总结
模板方法模式通过定义通用流程模板,让子类实现具体细节,实现了"流程统一,细节各异"的效果。
关键知识点
- • 组成部分:抽象类、具体子类、模板方法、基本方法
下次遇到多个类有相似流程的情况,不妨试试模板方法模式,它会像咖啡店的"流程大师"一样,帮你消除重复代码,让代码结构更清晰,开发效率更高。
该文章在 2026/1/23 12:02:58 编辑过