C# 设计模式详解

设计模式是软件设计中常见问题的通用解决方案。C# 作为一门现代面向对象语言,完美支持 23 种经典 GoF(Gang of Four)设计模式,并在 .NET 生态中有大量实际应用。

以下按 创建型、结构型、行为型 三大类,结合 C# 语法特性(如属性、委托、泛型、异步、LINQ 等)进行详细讲解,并附 完整可运行代码示例。


一、创建型模式(Creational Patterns)

关注对象创建机制,解耦对象创建与使用。


1. 单例模式(Singleton)

目的:确保一个类只有一个实例,并提供全局访问点。

public sealed class Singleton
{
    private static readonly Lazy<Singleton> _instance = 
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance => _instance.Value;

    private Singleton() { }

    public void DoSomething() => Console.WriteLine("Singleton is working!");
}

线程安全:使用 Lazy<T> 是 .NET 推荐的线程安全单例写法。


2. 工厂方法(Factory Method)

目的:定义创建对象的接口,让子类决定实例化哪一个类。

abstract class Product { public abstract void Operation(); }

class ConcreteProductA : Product { public override void Operation() => Console.WriteLine("Product A"); }
class ConcreteProductB : Product { public override void Operation() => Console.WriteLine("Product B"); }

abstract class Creator
{
    public abstract Product CreateProduct();
    public void Execute() => CreateProduct().Operation();
}

class ConcreteCreatorA : Creator
{
    public override Product CreateProduct() => new ConcreteProductA();
}

3. 抽象工厂(Abstract Factory)

目的:提供一个接口,用于创建一系列相关或依赖的对象。

interface IButton { void Render(); }
interface ICheckbox { void Check(); }

class WinButton : IButton { public void Render() => Console.WriteLine("Windows Button"); }
class MacButton : IButton { public void Render() => Console.WriteLine("Mac Button"); }

class WinCheckbox : ICheckbox { public void Check() => Console.WriteLine("Windows Checkbox"); }
class MacCheckbox : ICheckbox { public void Check() => Console.WriteLine("Mac Checkbox"); }

interface IGUIFactory
{
    IButton CreateButton();
    ICheckbox CreateCheckbox();
}

class WinFactory : IGUIFactory
{
    public IButton CreateButton() => new WinButton();
    public ICheckbox CreateCheckbox() => new WinCheckbox();
}

class MacFactory : IGUIFactory
{
    public IButton CreateButton() => new MacButton();
    public ICheckbox CreateCheckbox() => new MacCheckbox();
}

4. 建造者模式(Builder)

目的:分离复杂对象的构造与表示,相同构造过程可创建不同表示。

public class Car
{
    public string Engine { get; set; }
    public string Wheels { get; set; }
    public bool GPS { get; set; }

    public override string ToString() => 
        $"Engine: {Engine}, Wheels: {Wheels}, GPS: {GPS}";
}

public interface ICarBuilder
{
    void BuildEngine();
    void BuildWheels();
    void InstallGPS();
    Car GetCar();
}

public class SportsCarBuilder : ICarBuilder
{
    private Car _car = new Car();
    public void BuildEngine() => _car.Engine = "V8 Turbo";
    public void BuildWheels() => _car.Wheels = "20-inch Alloy";
    public void InstallGPS() => _car.GPS = true;
    public Car GetCar() => _car;
}

public class CarDirector
{
    public void Construct(ICarBuilder builder)
    {
        builder.BuildEngine();
        builder.BuildWheels();
        builder.InstallGPS();
    }
}

5. 原型模式(Prototype)

目的:通过复制现有对象来创建新对象,避免昂贵的创建过程。

public interface IPrototype<T> where T : class
{
    T Clone();
}

public class Person : IPrototype<Person>
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person Clone() => this.MemberwiseClone() as Person;

    public override string ToString() => $"{Name}, {Age}";
}

// 使用
var p1 = new Person { Name = "Tom", Age = 30 };
var p2 = p1.Clone();
p2.Name = "Jerry";

注意:MemberwiseClone 是浅拷贝,引用类型需深拷贝。


二、结构型模式(Structural Patterns)

关注类和对象的组合。


6. 适配器模式(Adapter)

目的:将不兼容的接口转换为客户端期望的接口。

// 旧系统接口
public interface IOldPrinter
{
    void Print(string text);
}

public class OldPrinter : IOldPrinter
{
    public void Print(string text) => Console.WriteLine("Old: " + text);
}

// 新系统期望接口
public interface INewPrinter
{
    void PrintDocument(string content);
}

// 适配器
public class PrinterAdapter : INewPrinter
{
    private readonly IOldPrinter _oldPrinter;
    public PrinterAdapter(IOldPrinter oldPrinter) => _oldPrinter = oldPrinter;

    public void PrintDocument(string content) => _oldPrinter.Print(content);
}

7. 装饰器模式(Decorator)

目的:动态地给对象添加职责。

public interface ICoffee
{
    string GetDescription();
    double GetCost();
}

public class SimpleCoffee : ICoffee
{
    public string GetDescription() => "Simple Coffee";
    public double GetCost() => 2.0;
}

public abstract class CoffeeDecorator : ICoffee
{
    protected ICoffee _coffee;
    protected CoffeeDecorator(ICoffee coffee) => _coffee = coffee;
    public virtual string GetDescription() => _coffee.GetDescription();
    public virtual double GetCost() => _coffee.GetCost();
}

public class MilkDecorator : CoffeeDecorator
{
    public MilkDecorator(ICoffee coffee) : base(coffee) { }
    public override string GetDescription() => _coffee.GetDescription() + ", Milk";
    public override double GetCost() => _coffee.GetCost() + 0.5;
}

8. 代理模式(Proxy)

目的:为其他对象提供代理以控制访问。

public interface IImage
{
    void Display();
}

public class RealImage : IImage
{
    private string _filename;
    public RealImage(string filename)
    {
        _filename = filename;
        LoadFromDisk();
    }
    private void LoadFromDisk() => Console.WriteLine($"Loading {_filename}");
    public void Display() => Console.WriteLine($"Displaying {_filename}");
}

public class ProxyImage : IImage
{
    private RealImage _realImage;
    private string _filename;

    public ProxyImage(string filename) => _filename = filename;

    public void Display()
    {
        _realImage ??= new RealImage(_filename);
        _realImage.Display();
    }
}

9. 组合模式(Composite)

目的:将对象组合成树形结构以表示“部分-整体”层次。

public abstract class Component
{
    protected string Name;
    protected Component(string name) => Name = name;
    public abstract void Display(int depth);
}

public class Leaf : Component
{
    public Leaf(string name) : base(name) { }
    public override void Display(int depth) => 
        Console.WriteLine(new string('-', depth) + Name);
}

public class Composite : Component
{
    private List<Component> _children = new List<Component>();
    public Composite(string name) : base(name) { }

    public void Add(Component c) => _children.Add(c);
    public void Remove(Component c) => _children.Remove(c);

    public override void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + Name);
        foreach (var c in _children)
            c.Display(depth + 2);
    }
}

10. 桥接模式(Bridge)

目的:将抽象与实现分离,使两者可独立变化。

public interface IRenderer
{
    void RenderCircle(float radius);
}

public class VectorRenderer : IRenderer
{
    public void RenderCircle(float radius) => Console.WriteLine($"Vector circle: {radius}");
}

public class RasterRenderer : IRenderer
{
    public void RenderCircle(float radius) => Console.WriteLine($"Raster pixels: {radius}");
}

public abstract class Shape
{
    protected IRenderer _renderer;
    protected Shape(IRenderer renderer) => _renderer = renderer;
    public abstract void Draw();
}

public class Circle : Shape
{
    private float _radius;
    public Circle(IRenderer renderer, float radius) : base(renderer) => _radius = radius;
    public override void Draw() => _renderer.RenderCircle(_radius);
}

三、行为型模式(Behavioral Patterns)

关注对象之间的责任分配。


11. 策略模式(Strategy)

目的:定义一系列算法,封装起来,使它们可相互替换。

public interface IPaymentStrategy
{
    void Pay(double amount);
}

public class CreditCardPayment : IPaymentStrategy
{
    public void Pay(double amount) => Console.WriteLine($"Paid {amount} via Credit Card");
}

public class PayPalPayment : IPaymentStrategy
{
    public void Pay(double amount) => Console.WriteLine($"Paid {amount} via PayPal");
}

public class ShoppingCart
{
    private IPaymentStrategy _strategy;
    public void SetPaymentStrategy(IPaymentStrategy strategy) => _strategy = strategy;
    public void Checkout(double amount) => _strategy.Pay(amount);
}

12. 观察者模式(Observer)—— 事件与委托

C# 原生支持:使用 event 和委托。

public class Subject
{
    public event Action<int> ValueChanged;

    private int _value;
    public int Value
    {
        get => _value;
        set
        {
            _value = value;
            ValueChanged?.Invoke(_value);
        }
    }
}

var subject = new Subject();
subject.ValueChanged += (v) => Console.WriteLine($"Value changed to {v}");
subject.Value = 42;

13. 命令模式(Command)

目的:将请求封装为对象,支持撤销、排队等。

public interface ICommand
{
    void Execute();
    void Undo();
}

public class Light
{
    public void On() => Console.WriteLine("Light On");
    public void Off() => Console.WriteLine("Light Off");
}

public class LightOnCommand : ICommand
{
    private Light _light;
    public LightOnCommand(Light light) => _light = light;
    public void Execute() => _light.On();
    public void Undo() => _light.Off();
}

public class RemoteControl
{
    private ICommand _command;
    public void SetCommand(ICommand command) => _command = command;
    public void PressButton() => _command.Execute();
    public void PressUndo() => _command.Undo();
}

14. 责任链模式(Chain of Responsibility)

目的:使多个对象都有机会处理请求。

public abstract class Handler
{
    protected Handler _next;
    public void SetNext(Handler next) => _next = next;
    public abstract void HandleRequest(int request);
}

public class ConcreteHandler1 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request < 10)
            Console.WriteLine($"Handler1 handled {request}");
        else
            _next?.HandleRequest(request);
    }
}

15. 迭代器模式(Iterator)—— IEnumerable<T>

C# 内置支持:

public class MyCollection : IEnumerable<int>
{
    private int[] _data = { 1, 2, 3, 4, 5 };

    public IEnumerator<int> GetEnumerator() => 
        ((IEnumerable<int>)_data).GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

// 使用
foreach (var item in new MyCollection())
    Console.WriteLine(item);

16. 中介者模式(Mediator)

目的:降低对象间耦合,通过中介者通信。

public interface IMediator
{
    void Send(string message, Colleague colleague);
}

public abstract class Colleague
{
    protected IMediator _mediator;
    protected Colleague(IMediator mediator) => _mediator = mediator;
}

public class ConcreteColleague1 : Colleague
{
    public ConcreteColleague1(IMediator mediator) : base(mediator) { }
    public void Send(string msg) => _mediator.Send(msg, this);
    public void Notify(string msg) => Console.WriteLine("C1: " + msg);
}

17. 备忘录模式(Memento)

目的:在不破坏封装的前提下,捕获并恢复对象状态。

public class Memento
{
    public int State { get; }
    public Memento(int state) => State = state;
}

public class Originator
{
    public int State { get; set; }
    public Memento Save() => new Memento(State);
    public void Restore(Memento m) => State = m.State;
}

18. 状态模式(State)

目的:允许对象在内部状态改变时改变行为。

public interface IState
{
    void Handle(Context context);
}

public class ConcreteStateA : IState
{
    public void Handle(Context context)
    {
        Console.WriteLine("State A");
        context.State = new ConcreteStateB();
    }
}

public class Context
{
    public IState State { get; set; }
    public Context(IState state) => State = state;
    public void Request() => State.Handle(this);
}

19. 访问者模式(Visitor)

目的:在不改变对象结构的前提下,添加新操作。

public interface IVisitor
{
    void Visit(ElementA element);
    void Visit(ElementB element);
}

public abstract class Element
{
    public abstract void Accept(IVisitor visitor);
}

public class ElementA : Element
{
    public override void Accept(IVisitor visitor) => visitor.Visit(this);
    public void OperationA() => Console.WriteLine("ElementA operation");
}

20. 模板方法模式(Template Method)

目的:定义算法骨架,子类实现具体步骤。

public abstract class Game
{
    public void Play()
    {
        Initialize();
        StartPlay();
        EndPlay();
    }

    protected abstract void Initialize();
    protected abstract void StartPlay();
    protected abstract void EndPlay();
}

public class Cricket : Game
{
    protected override void Initialize() => Console.WriteLine("Cricket Initialized");
    protected override void StartPlay() => Console.WriteLine("Cricket Started");
    protected override void EndPlay() => Console.WriteLine("Cricket Finished");
}

21. 解释器模式(Interpreter)

目的:为语言创建解释器(较少用,LINQ Expression 类似)。


22. 空对象模式(Null Object)—— 非 GoF,但实用

public interface ILogger
{
    void Log(string message);
}

public class ConsoleLogger : ILogger
{
    public void Log(string message) => Console.WriteLine(message);
}

public class NullLogger : ILogger
{
    public void Log(string message) { } // 什么都不做
}

// 使用时无需 null 检查
ILogger logger = new NullLogger();
logger.Log("test"); // 安全

四、.NET 中常见设计模式应用

模式.NET 示例
观察者event, IObservable<T>
迭代器IEnumerable<T>, yield return
策略依赖注入(DI)中的服务替换
装饰器ASP.NET Middleware
工厂IServiceProvider, ActivatorUtilities
建造者StringBuilder, HttpClient 配置
适配器StreamReader 适配 Stream

五、总结表格

类别模式核心思想
创建型单例、工厂、建造者、原型控制对象创建
结构型适配器、装饰器、代理、组合组合对象结构
行为型策略、观察者、命令、状态分配行为责任

六、推荐学习资源

  • 《设计模式:可复用面向对象软件的基础》(GoF)
  • 《Head First 设计模式》(C# 版)
  • Microsoft Docs: 设计模式

更多推荐