1. 设计模式概述与核心价值
设计模式是软件开发中针对常见问题的经典解决方案模板。作为C#开发者,掌握23种经典设计模式能显著提升代码质量、可维护性和扩展性。这些模式最早由GoF(Gang of Four)在《设计模式:可复用面向对象软件的基础》中系统化提出,历经20余年验证仍被广泛使用。
在实际项目中,设计模式的价值主要体现在三个方面:
- 代码复用:避免重复造轮子,直接套用成熟方案
- 架构清晰:通过标准模式组织代码结构,降低理解成本
- 应对变化:通过松耦合设计提高系统可扩展性
注意:设计模式不是银弹,过度使用会导致代码过度工程化。建议在真正需要解决特定问题时再引入对应模式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 创建型模式解析与C#实现
2.1 单例模式(Singleton)
确保类只有一个实例的经典模式。C#中有多种实现方式:
csharp复制// 双重检查锁实现(线程安全)
public class Singleton
{
private static volatile Singleton _instance;
private static readonly object _lock = new object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
}
适用场景:
- 配置管理类
- 日志记录器
- 资源管理器
常见误区:
- 忽视线程安全导致多实例
- 滥用单例造成全局状态污染
2.2 工厂方法模式(Factory Method)
定义创建对象的接口,让子类决定实例化哪个类:
csharp复制public interface IProduct
{
void Operation();
}
public abstract class Creator
{
public abstract IProduct FactoryMethod();
public void SomeOperation()
{
var product = FactoryMethod();
product.Operation();
}
}
public class ConcreteCreator : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProduct();
}
}
优势:
- 符合开闭原则
- 客户端代码与具体类解耦
2.3 抽象工厂模式(Abstract Factory)
创建相关或依赖对象的家族,而不需要指定具体类:
csharp复制public interface IAbstractFactory
{
IProductA CreateProductA();
IProductB CreateProductB();
}
public class ConcreteFactory1 : IAbstractFactory
{
public IProductA CreateProductA() => new ProductA1();
public IProductB CreateProductB() => new ProductB1();
}
典型应用:
- UI主题切换
- 跨平台组件创建
3. 结构型模式深度剖析
3.1 适配器模式(Adapter)
使不兼容接口能够协同工作:
csharp复制public interface ITarget
{
void Request();
}
public class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
public class Adapter : ITarget
{
private readonly Adaptee _adaptee;
public Adapter(Adaptee adaptee)
{
_adaptee = adaptee;
}
public void Request()
{
_adaptee.SpecificRequest();
}
}
使用场景:
- 集成第三方库
- 旧系统改造
3.2 装饰器模式(Decorator)
动态添加职责到对象:
csharp复制public abstract class Component
{
public abstract void Operation();
}
public class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("ConcreteComponent.Operation()");
}
}
public abstract class Decorator : Component
{
protected Component _component;
public Decorator(Component component)
{
_component = component;
}
}
public class ConcreteDecoratorA : Decorator
{
public ConcreteDecoratorA(Component component) : base(component) {}
public override void Operation()
{
_component.Operation();
AddedBehavior();
}
private void AddedBehavior()
{
Console.WriteLine("Added behavior from ConcreteDecoratorA");
}
}
优势:
- 比继承更灵活
- 避免子类爆炸
4. 行为型模式实战应用
4.1 观察者模式(Observer)
定义对象间的一对多依赖关系:
csharp复制public interface IObserver
{
void Update(ISubject subject);
}
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
public class Subject : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
public void Attach(IObserver observer)
{
_observers.Add(observer);
}
public void Detach(IObserver observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach(var observer in _observers)
observer.Update(this);
}
}
C#简化实现:
csharp复制public class EventSubject
{
public event Action<string> OnEvent;
public void TriggerEvent(string data)
{
OnEvent?.Invoke(data);
}
}
4.2 策略模式(Strategy)
定义算法族,封装每个算法:
csharp复制public interface IStrategy
{
void Execute();
}
public class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
_strategy = strategy;
}
public void ExecuteStrategy()
{
_strategy.Execute();
}
}
现代C#实现:
csharp复制public class ModernContext
{
private readonly Action _strategy;
public ModernContext(Action strategy)
{
_strategy = strategy;
}
public void Execute() => _strategy();
}
5. 模式选择与组合实践
5.1 模式组合案例:MVVM架构
典型模式组合应用:
- 观察者模式:数据绑定
- 命令模式:ICommand实现
- 适配器模式:数据转换器
csharp复制public class ViewModel : INotifyPropertyChanged
{
private string _name;
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get => _name;
set
{
_name = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(Name)));
}
}
public ICommand SubmitCommand { get; }
public ViewModel()
{
SubmitCommand = new RelayCommand(Submit);
}
private void Submit(object parameter)
{
// 命令逻辑
}
}
5.2 模式选择决策树
| 问题特征 | 候选模式 |
|---|---|
| 需要控制实例创建 | 单例、工厂、建造者 |
| 接口不兼容 | 适配器、外观 |
| 需要动态添加功能 | 装饰器、代理 |
| 算法需要切换 | 策略、模板方法 |
| 对象状态变化通知 | 观察者、中介者 |
6. 性能考量与最佳实践
6.1 模式性能影响
| 模式 | 内存开销 | CPU开销 | 适用场景 |
|---|---|---|---|
| 单例 | 低 | 低 | 全局访问点 |
| 装饰器 | 中 | 中 | 动态扩展 |
| 观察者 | 可变 | 可变 | 事件驱动 |
6.2 实际应用建议
- 避免模式滥用:简单场景直接实现,不要为了模式而模式
- 关注可测试性:依赖注入优于直接使用单例
- 利用语言特性:C#的event、delegate可简化观察者等模式
- 考虑异步场景:现代应用需注意线程安全问题
csharp复制// 线程安全的观察者模式实现
public class AsyncSubject
{
private readonly ConcurrentDictionary<IObserver, bool> _observers = new();
public void Subscribe(IObserver observer)
{
_observers.TryAdd(observer, true);
}
public async Task NotifyAsync()
{
var tasks = _observers.Keys.Select(o => Task.Run(() => o.Update(this)));
await Task.WhenAll(tasks);
}
}
在多年C#开发实践中,我发现设计模式的价值不在于记住所有实现细节,而是理解其核心思想。当遇到特定问题时,能够快速识别适用的模式并合理调整实现。特别是在大型项目维护中,规范使用设计模式可以显著降低代码维护成本。
