📅 Day 25:高级设计模式与 SOLID 原则实践
✅ 学习目标:
- 理解 SOLID 原则 及其在面向对象设计中的重要性;
- 掌握几种常见的 高级设计模式,包括:
- 观察者模式(Observer)
- 装饰器模式(Decorator)
- 责任链模式(Chain of Responsibility)
- 命令模式(Command)
- 理解这些模式的适用场景和实现方式;
- 结合 SOLID 原则优化代码结构;
- 编写一个结合多个高级设计模式的实战项目(如订单处理系统);
- 提升你对模块化、可扩展性和可维护性的理解。
🧠 一、什么是 SOLID 原则?
SOLID 是五个面向对象设计原则的缩写,由 Robert C. Martin 提出,用于指导我们写出更健壮、易维护的代码。
缩写 | 全称 | 中文含义 |
---|---|---|
S | Single Responsibility Principle | 单一职责原则 |
O | Open/Closed Principle | 开放封闭原则 |
L | Liskov Substitution Principle | 里氏替换原则 |
I | Interface Segregation Principle | 接口隔离原则 |
D | Dependency Inversion Principle | 依赖倒置原则 |
示例说明:
✅ 单一职责原则(SRP):
一个类只做一件事。例如:一个
Logger
类只负责日志记录,不处理业务逻辑。
✅ 开放封闭原则(OCP):
对扩展开放,对修改关闭。新增功能应通过继承或组合完成,而不是修改已有代码。
✅ 里氏替换原则(LSP):
所有引用基类的地方必须能透明地使用其子类的对象。
✅ 接口隔离原则(ISP):
客户端不应依赖它不需要的接口。将大接口拆分为更细粒度的小接口。
✅ 依赖倒置原则(DIP):
高层模块不应该依赖低层模块,两者都应该依赖抽象(接口)。抽象不应依赖细节,细节应依赖抽象。
🔁 二、高级设计模式详解与示例
1️⃣ 观察者模式(Observer Pattern)
用途:定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。
public interface IObserver
{
void Update(string message);
}
public class NewsSubscriber : IObserver
{
private string _name;
public NewsSubscriber(string name) => _name = name;
public void Update(string message)
{
Console.WriteLine($"{_name} 收到新闻:{message}");
}
}
public class NewsPublisher
{
private List<IObserver> _subscribers = new();
public void Subscribe(IObserver observer) => _subscribers.Add(observer);
public void Unsubscribe(IObserver observer) => _subscribers.Remove(observer);
public void Notify(string message)
{
foreach (var subscriber in _subscribers)
subscriber.Update(message);
}
public void PublishNews(string news) => Notify(news);
}
使用:
var publisher = new NewsPublisher();
var sub1 = new NewsSubscriber("用户A");
var sub2 = new NewsSubscriber("用户B");
publisher.Subscribe(sub1);
publisher.Subscribe(sub2);
publisher.PublishNews("C# 12 发布了!");
✅ 适用场景:事件系统、消息队列、UI 更新、日志通知等。
2️⃣ 装饰器模式(Decorator Pattern)
用途:动态地给对象添加职责,比继承更灵活,避免类爆炸问题。
public interface ICoffee
{
string GetDescription();
decimal Cost();
}
public class SimpleCoffee : ICoffee
{
public string GetDescription() => "普通咖啡";
public decimal Cost() => 2.0m;
}
public class MilkDecorator : ICoffee
{
private readonly ICoffee _coffee;
public MilkDecorator(ICoffee coffee) => _coffee = coffee;
public string GetDescription() => _coffee.GetDescription() + ", 加奶";
public decimal Cost() => _coffee.Cost() + 0.5m;
}
public class SugarDecorator : ICoffee
{
private readonly ICoffee _coffee;
public SugarDecorator(ICoffee coffee) => _coffee = coffee;
public string GetDescription() => _coffee.GetDescription() + ", 加糖";
public decimal Cost() => _coffee.Cost() + 0.2m;
}
使用:
ICoffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
Console.WriteLine($"{coffee.GetDescription()},价格:{coffee.Cost():C}");
// 输出:普通咖啡, 加奶, 加糖,价格:$2.70
✅ 适用场景:组件功能扩展、权限增强、数据格式转换等。
3️⃣ 责任链模式(Chain of Responsibility Pattern)
用途:让多个对象有机会处理请求,从而避免请求发送者与接收者之间的耦合。
public abstract class Handler
{
protected Handler _nextHandler;
public void SetNext(Handler nextHandler) => _nextHandler = nextHandler;
public abstract void HandleRequest(int request);
}
public class ManagerHandler : Handler
{
public override void HandleRequest(int request)
{
if (request <= 1000)
Console.WriteLine("经理批准了报销申请:" + request);
else if (_nextHandler != null)
_nextHandler.HandleRequest(request);
}
}
public class DirectorHandler : Handler
{
public override void HandleRequest(int request)
{
if (request <= 5000)
Console.WriteLine("总监批准了报销申请:" + request);
else if (_nextHandler != null)
_nextHandler.HandleRequest(request);
}
}
public class CEOHandler : Handler
{
public override void HandleRequest(int request)
{
Console.WriteLine("CEO批准了报销申请:" + request);
}
}
使用:
var manager = new ManagerHandler();
var director = new DirectorHandler();
var ceo = new CEOHandler();
manager.SetNext(director);
director.SetNext(ceo);
manager.HandleRequest(800); // 经理处理
manager.HandleRequest(3000); // 总监处理
manager.HandleRequest(10000); // CEO 处理
✅ 适用场景:审批流程、异常处理链、请求过滤等。
4️⃣ 命令模式(Command Pattern)
用途:将请求封装为对象,从而使你可以用不同的请求对客户进行参数化。
public interface ICommand
{
void Execute();
}
public class LightOnCommand : ICommand
{
private readonly Light _light;
public LightOnCommand(Light light) => _light = light;
public void Execute() => _light.TurnOn();
}
public class LightOffCommand : ICommand
{
private readonly Light _light;
public LightOffCommand(Light light) => _light = light;
public void Execute() => _light.TurnOff();
}
public class Light
{
public void TurnOn() => Console.WriteLine("灯打开了");
public void TurnOff() => Console.WriteLine("灯关掉了");
}
public class RemoteControl
{
private ICommand _command;
public void SetCommand(ICommand command) => _command = command;
public void PressButton()
{
if (_command != null)
_command.Execute();
}
}
使用:
var light = new Light();
var remote = new RemoteControl();
remote.SetCommand(new LightOnCommand(light));
remote.PressButton(); // 输出:灯打开了
remote.SetCommand(new LightOffCommand(light));
remote.PressButton(); // 输出:灯关掉了
✅ 适用场景:操作回滚/撤销、事务管理、远程控制、宏命令等。
💪 实战练习:订单处理系统
功能要求:
- 用户提交订单后,触发多个后续操作:
- 记录日志(观察者)
- 检查库存(责任链)
- 应用折扣策略(策略模式)
- 发送邮件通知(装饰器 / 命令)
- 使用 SOLID 原则设计系统结构;
- 各组件之间松耦合,易于扩展和测试。
示例代码框架:
class Program
{
static void Main()
{
var order = new Order { TotalAmount = 200.00m };
var discountStrategy = new TenPercentDiscount();
var emailNotifier = new EmailNotifier();
// 添加观察者
OrderService.Instance.Subscribe(emailNotifier);
// 应用策略
var cart = new ShoppingCart(discountStrategy);
decimal finalPrice = cart.Checkout(order.TotalAmount);
// 责任链处理
var inventoryHandler = new InventoryCheckHandler();
var paymentHandler = new PaymentProcessingHandler();
inventoryHandler.SetNext(paymentHandler);
inventoryHandler.HandleOrder(order);
Console.WriteLine($"最终支付金额:{finalPrice:C}");
}
}
📝 小结
今天你学会了:
- 什么是 SOLID 原则,以及它们在软件设计中的作用;
- 掌握了四种常见的 高级设计模式:观察者、装饰器、责任链、命令;
- 理解了每种模式的典型应用场景;
- 编写了一个结合多种高级设计模式的订单处理系统;
- 学会了如何利用设计模式提升系统的灵活性、可维护性和可测试性。
掌握这些高级设计模式和 SOLID 原则,将帮助你在构建大型应用、微服务架构、插件系统等复杂场景中写出更高质量的代码。
🧩 下一步学习方向(Day 26)
明天我们将进入一个新的主题 —— C# 异步编程进阶(Advanced Async Programming),你将学会:
ConfigureAwait(false)
的原理与使用场景;- 如何避免死锁;
- 并行任务(
Parallel
,PLINQ
); - 自定义异步状态机;
- 使用
ValueTask
替代Task
的优化技巧; - 构建高性能异步 API。