以下是关于C#中设计模式的综合介绍,结合其核心概念、分类、常见模式及应用场景:
一、设计模式概述
设计模式是解决软件设计中常见问题的可复用方案,通过标准化代码结构提升可维护性、扩展性和复用性。在C#中,设计模式基于面向对象编程(OOP)原则,结合.NET框架特性,广泛应用于企业级开发 。
二、设计原则
设计模式的基础是以下核心原则 :
-
单一职责原则(SRP):一个类应仅有一个引起变化的原因。
-
开闭原则(OCP):对扩展开放,对修改关闭。
-
里氏替换原则(LSP):子类必须能替换父类且不影响程序行为。
-
依赖倒置原则(DIP):高层模块不依赖低层模块,均依赖抽象。
-
接口隔离原则(ISP):客户端不应依赖其不需要的接口。
-
迪米特法则(LoD):减少对象间的直接依赖,通过中介通信。
三、设计模式分类
在C#开发中,设计模式被广泛应用于解决特定场景下的代码设计问题,以下是常见的几种设计模式及其典型应用场景和实现方式:
(一)创建型模式(处理对象创建)
-
单例模式 (Singleton)
- 确保一个类只有一个实例,并提供全局访问点。
- 示例:数据库连接池、配置管理器。
-
工厂方法模式 (Factory Method)
- 定义一个创建对象的接口,由子类决定实例化哪个类。
- 示例:日志记录器(文件日志、数据库日志)。
-
抽象工厂模式 (Abstract Factory)
- 创建一组相关或依赖对象的家族,无需指定具体类。
- 示例:跨平台 UI 组件库(Windows/Mac 按钮、文本框)。
-
建造者模式 (Builder)
- 分步骤创建复杂对象,分离构造过程与表示。
- 示例:生成不同格式的文档(HTML、PDF)。
-
原型模式 (Prototype)
- 通过复制现有对象来创建新对象。
- 示例:游戏中的敌人克隆、配置模板复制。
(二)结构型模式(处理对象组合)
-
适配器模式 (Adapter)
- 让接口不兼容的类可以协同工作。
- 示例:旧版接口适配到新系统。
-
桥接模式 (Bridge)
- 将抽象与实现分离,使两者可独立变化。
- 示例:图形渲染引擎(不同 API:OpenGL/Vulkan)。
-
组合模式 (Composite)
- 用树形结构表示“部分-整体”层次结构。
- 示例:文件系统(文件与文件夹的统一操作)。
-
装饰器模式 (Decorator)
- 动态地为对象添加职责。
- 示例:为咖啡添加配料(加糖、加奶)。
-
外观模式 (Facade)
- 提供简化复杂子系统的统一接口。
- 示例:一键编译工具(封装编译、测试、打包步骤)。
-
享元模式 (Flyweight)
- 共享大量细粒度对象以减少内存占用。
- 示例:文本编辑器中的字符对象池。
-
代理模式 (Proxy)
- 控制对其他对象的访问(延迟加载、权限控制等)。
- 示例:图片懒加载、远程服务代理。
(三)行为型模式(处理对象间通信)
-
责任链模式 (Chain of Responsibility)
- 多个对象依次处理请求,直到有对象处理它。
- 示例:审批流程(经理→总监→CEO)。
-
命令模式 (Command)
- 将请求封装为对象,支持撤销、队列等操作。
- 示例:GUI 按钮操作、事务管理。
-
解释器模式 (Interpreter)
- 定义语言的语法规则并解释执行。
- 示例:正则表达式解析、数学公式计算。
-
迭代器模式 (Iterator)
- 提供遍历集合对象的方法,无需暴露内部结构。
- 示例:遍历树形结构、数据库查询结果。
-
中介者模式 (Mediator)
- 减少对象间的直接耦合,通过中介者通信。
- 示例:聊天室(用户不直接对话,通过服务器转发)。
-
备忘录模式 (Memento)
- 保存对象状态,以便后续恢复。
- 示例:文本编辑器的撤销功能。
-
观察者模式 (Observer)
- 定义对象间的一对多依赖,状态变化时通知所有依赖者。
- 示例:事件监听、消息推送系统。
-
状态模式 (State)
- 允许对象在内部状态改变时改变行为。
- 示例:订单状态(待支付→已支付→已发货)。
-
策略模式 (Strategy)
- 定义算法族,使其可以互相替换。
- 示例:支付方式(支付宝、微信、信用卡)。
-
模板方法模式 (Template Method)
- 定义算法骨架,子类实现某些步骤。
- 示例:数据导出流程(准备数据→生成文件→发送通知)。
-
访问者模式 (Visitor)
- 将操作与对象结构分离,便于新增操作。
- 示例:文档导出(导出为 XML、JSON)。
四、C#设计模式的应用示例
1. 单例模式(Singleton Pattern)
单例模式确保一个类只有一个实例,并提供全局访问点。
public class Singleton
{
private static Singleton _instance;
// 私有构造函数,防止外部实例化
private Singleton() { }
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
2. 工厂模式(Factory Pattern)
工厂模式提供一个创建对象的接口,但由子类决定实例化哪个类。
public interface IProduct
{
string GetName();
}
public class ConcreteProductA : IProduct
{
public string GetName() => "Product A";
}
public class ConcreteProductB : IProduct
{
public string GetName() => "Product B";
}
public class ProductFactory
{
public static IProduct CreateProduct(string type)
{
if (type == "A")
return new ConcreteProductA();
else if (type == "B")
return new ConcreteProductB();
else
throw new ArgumentException("Invalid product type");
}
}
// 使用示例
var productA = ProductFactory.CreateProduct("A");
Console.WriteLine(productA.GetName()); // 输出: Product A
3. 观察者模式(Observer Pattern)
观察者模式定义了一对多的依赖关系,使得一个对象的状态变化可以通知所有依赖于它的对象。
using System;
using System.Collections.Generic;
public class Subject
{
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();
}
}
}
public interface IObserver
{
void Update();
}
public class ConcreteObserver : IObserver
{
public void Update()
{
Console.WriteLine("Observer notified!");
}
}
// 使用示例
var subject = new Subject();
var observer = new ConcreteObserver();
subject.Attach(observer);
subject.Notify(); // 输出: Observer notified!
4. 策略模式(Strategy Pattern)
策略模式定义了一系列算法,将每个算法封装起来,并使它们可以互换。
public interface IStrategy
{
int Execute(int a, int b);
}
public class AddStrategy : IStrategy
{
public int Execute(int a, int b) => a + b;
}
public class SubtractStrategy : IStrategy
{
public int Execute(int a, int b) => a - b;
}
public class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
_strategy = strategy;
}
public int ExecuteStrategy(int a, int b)
{
return _strategy.Execute(a, b);
}
}
// 使用示例
var context = new Context(new AddStrategy());
Console.WriteLine(context.ExecuteStrategy(3, 2)); // 输出: 5
context = new Context(new SubtractStrategy());
Console.WriteLine(context.ExecuteStrategy(3, 2)); // 输出: 1
5. 装饰者模式(Decorator Pattern)
装饰者模式允许用户在不修改对象结构的情况下,动态地添加功能。
public interface IComponent
{
string Operation();
}
public class ConcreteComponent : IComponent
{
public string Operation() => "ConcreteComponent";
}
public abstract class Decorator : IComponent
{
protected IComponent _component;
public Decorator(IComponent component)
{
_component = component;
}
public virtual string Operation() => _component.Operation();
}
public class ConcreteDecoratorA : Decorator
{
public ConcreteDecoratorA(IComponent component) : base(component) { }
public override string Operation() => $"ConcreteDecoratorA({base.Operation()})";
}
// 使用示例
IComponent component = new ConcreteComponent();
component = new ConcreteDecoratorA(component);
Console.WriteLine(component.Operation()); // 输出: ConcreteDecoratorA(ConcreteComponent)
6. 适配器模式(Adapter Pattern)
适配器模式允许将一个类的接口转换成客户端所期待的另一个接口。适配器模式使得原本因接口不兼容而无法一起工作的类可以一起工作。
public interface ITarget
{
string Request();
}
public class Adaptee
{
public string SpecificRequest()
{
return "Specific request.";
}
}
public class Adapter : ITarget
{
private Adaptee _adaptee;
public Adapter(Adaptee adaptee)
{
_adaptee = adaptee;
}
public string Request()
{
return _adaptee.SpecificRequest();
}
}
// 使用示例
Adaptee adaptee = new Adaptee();
ITarget target = new Adapter(adaptee);
Console.WriteLine(target.Request()); // 输出: Specific request.
7. 桥接模式(Bridge Pattern)
桥接模式用于将抽象部分与其实现部分分离,使它们可以独立变化。它通过组合而不是继承来实现。
public abstract class Abstraction
{
protected IImplementor _implementor;
protected Abstraction(IImplementor implementor)
{
_implementor = implementor;
}
public abstract void Operation();
}
public interface IImplementor
{
void Implementation();
}
public class ConcreteImplementorA : IImplementor
{
public void Implementation() => Console.WriteLine("ConcreteImplementorA Implementation");
}
public class RefinedAbstraction : Abstraction
{
public RefinedAbstraction(IImplementor implementor) : base(implementor) { }
public override void Operation()
{
Console.WriteLine("RefinedAbstraction Operation");
_implementor.Implementation();
}
}
// 使用示例
IImplementor implementor = new ConcreteImplementorA();
Abstraction abstraction = new RefinedAbstraction(implementor);
abstraction.Operation();
// 输出:
// RefinedAbstraction Operation
// ConcreteImplementorA Implementation
8. 组合模式(Composite Pattern)
组合模式允许将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。
public interface IComponent
{
void Operation();
}
public class Leaf : IComponent
{
public void Operation() => Console.WriteLine("Leaf operation");
}
public class Composite : IComponent
{
private List<IComponent> _children = new List<IComponent>();
public void Add(IComponent component) => _children.Add(component);
public void Remove(IComponent component) => _children.Remove(component);
public void Operation()
{
foreach (var child in _children)
{
child.Operation();
}
}
}
// 使用示例
Composite composite = new Composite();
composite.Add(new Leaf());
composite.Add(new Leaf());
composite.Operation(); // 输出: Leaf operation (两次)
9. 状态模式(State Pattern)
状态模式允许对象在其内部状态改变时改变其行为。它将状态行为封装在状态对象中,使得状态的变化更加清晰。
public interface IState
{
void Handle(Context context);
}
public class ConcreteStateA : IState
{
public void Handle(Context context)
{
Console.WriteLine("State A handling.");
context.State = new ConcreteStateB();
}
}
public class ConcreteStateB : IState
{
public void Handle(Context context)
{
Console.WriteLine("State B handling.");
context.State = new ConcreteStateA();
}
}
public class Context
{
public IState State { get; set; }
public void Request()
{
State.Handle(this);
}
}
// 使用示例
Context context = new Context();
context.State = new ConcreteStateA();
context.Request(); // 输出: State A handling.
context.Request(); // 输出: State B handling.
10. 命令模式(Command Pattern)
命令模式将请求封装为一个对象,从而使您可以使用不同的请求、排队请求和记录请求日志。它允许您将请求参数化。
public interface ICommand
{
void Execute();
}
public class ConcreteCommand : ICommand
{
private Receiver _receiver;
public ConcreteCommand(Receiver receiver)
{
_receiver = receiver;
}
public void Execute()
{
_receiver.Action();
}
}
public class Receiver
{
public void Action() => Console.WriteLine("Receiver action executed.");
}
public class Invoker
{
private ICommand _command;
public void SetCommand(ICommand command) => _command = command;
public void ExecuteCommand() => _command.Execute();
}
// 使用示例
Receiver receiver = new Receiver();
ICommand command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.SetCommand(command);
invoker.ExecuteCommand(); // 输出: Receiver action executed.