C# 23种设计模式详解与示例

C# 23种设计模式详解与示例

    • 一、创建型模式(5种)
      • [1. 单例模式 (Singleton)](#1. 单例模式 (Singleton))
      • [2. 工厂方法模式 (Factory Method)](#2. 工厂方法模式 (Factory Method))
      • [3. 抽象工厂模式 (Abstract Factory)](#3. 抽象工厂模式 (Abstract Factory))
      • [4. 建造者模式 (Builder)](#4. 建造者模式 (Builder))
      • [5. 原型模式 (Prototype)](#5. 原型模式 (Prototype))
    • 二、结构型模式(7种)
      • [6. 适配器模式 (Adapter)](#6. 适配器模式 (Adapter))
      • [7. 桥接模式 (Bridge)](#7. 桥接模式 (Bridge))
      • [8. 组合模式 (Composite)](#8. 组合模式 (Composite))
      • [9. 装饰器模式 (Decorator)](#9. 装饰器模式 (Decorator))
      • [10. 外观模式 (Facade)](#10. 外观模式 (Facade))
      • [11. 享元模式 (Flyweight)](#11. 享元模式 (Flyweight))
      • [12. 代理模式 (Proxy)](#12. 代理模式 (Proxy))
    • 三、行为型模式(11种)
      • [13. 责任链模式 (Chain of Responsibility)](#13. 责任链模式 (Chain of Responsibility))
      • [14. 命令模式 (Command)](#14. 命令模式 (Command))
      • [15. 解释器模式 (Interpreter)](#15. 解释器模式 (Interpreter))
      • [16. 迭代器模式 (Iterator)](#16. 迭代器模式 (Iterator))
      • [17. 中介者模式 (Mediator)](#17. 中介者模式 (Mediator))
      • [18. 备忘录模式 (Memento)](#18. 备忘录模式 (Memento))
      • [19. 观察者模式 (Observer)](#19. 观察者模式 (Observer))
      • [20. 状态模式 (State)](#20. 状态模式 (State))
      • [21. 策略模式 (Strategy)](#21. 策略模式 (Strategy))
      • [22. 模板方法模式 (Template Method)](#22. 模板方法模式 (Template Method))
      • [23. 访问者模式 (Visitor)](#23. 访问者模式 (Visitor))
    • 总结

设计模式是软件设计中常见问题的典型解决方案,它们是可以重复使用的设计模板。GoF(Gang of Four)提出的23种设计模式分为三大类:创建型、结构型和行为型。

一、创建型模式(5种)

1. 单例模式 (Singleton)

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

csharp 复制代码
public sealed class Singleton  // sealed关键字防止继承
{
    // 静态实例变量
    private static Singleton _instance;
    // 锁对象,用于线程安全
    private static readonly object _lock = new object();

    // 私有构造函数,防止外部实例化
    private Singleton() { }

    // 公共静态方法获取唯一实例
    public static Singleton GetInstance()
    {
        // 双重检查锁定,提高性能
        if (_instance == null)  // 第一次检查
        {
            lock (_lock)  // 加锁确保线程安全
            {
                if (_instance == null)  // 第二次检查
                {
                    _instance = new Singleton();  // 创建唯一实例
                }
            }
        }
        return _instance;  // 返回唯一实例
    }
}

// 使用示例
var instance1 = Singleton.GetInstance();  // 获取第一个实例
var instance2 = Singleton.GetInstance();  // 获取第二个实例
Console.WriteLine(instance1 == instance2); // 输出 True,证明是同一个实例

2. 工厂方法模式 (Factory Method)

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

csharp 复制代码
// 产品接口
public interface IProduct
{
    string Operation();  // 产品操作
}

// 具体产品A
public class ConcreteProductA : IProduct
{
    public string Operation() => "Result of ConcreteProductA";  // 实现具体操作
}

// 抽象创建者
public abstract class Creator
{
    // 抽象工厂方法,由子类实现
    public abstract IProduct FactoryMethod();
    
    // 业务逻辑方法
    public string SomeOperation()
    {
        var product = FactoryMethod();  // 调用工厂方法创建产品
        return $"Creator: {product.Operation()}";  // 使用产品
    }
}

// 具体创建者A
public class ConcreteCreatorA : Creator
{
    // 实现工厂方法,返回具体产品A
    public override IProduct FactoryMethod() => new ConcreteProductA();
}

// 使用示例
Creator creator = new ConcreteCreatorA();  // 创建具体创建者
Console.WriteLine(creator.SomeOperation());  // 执行业务逻辑

3. 抽象工厂模式 (Abstract Factory)

目的:提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。

csharp 复制代码
// 抽象工厂接口
public interface IAbstractFactory
{
    IProductA CreateProductA();  // 创建产品A
    IProductB CreateProductB();  // 创建产品B
}

// 产品A接口
public interface IProductA 
{ 
    string UsefulFunctionA();  // 产品A的功能
}

// 产品B接口
public interface IProductB 
{ 
    string UsefulFunctionB();  // 产品B的功能
}

// 具体工厂1
public class ConcreteFactory1 : IAbstractFactory
{
    // 创建具体产品A1
    public IProductA CreateProductA() => new ConcreteProductA1();
    
    // 创建具体产品B1
    public IProductB CreateProductB() => new ConcreteProductB1();
}

// 使用示例
IAbstractFactory factory = new ConcreteFactory1();  // 创建具体工厂
var productA = factory.CreateProductA();  // 创建产品A
var productB = factory.CreateProductB();  // 创建产品B
Console.WriteLine(productA.UsefulFunctionA());  // 使用产品A
Console.WriteLine(productB.UsefulFunctionB());  // 使用产品B

4. 建造者模式 (Builder)

目的:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

csharp 复制代码
// 产品类
public class Product
{
    public List<string> Parts { get; } = new List<string>();  // 部件列表
    
    public void Add(string part) => Parts.Add(part);  // 添加部件
    
    public string ListParts() => $"Parts: {string.Join(", ", Parts)}";  // 列出所有部件
}

// 建造者接口
public interface IBuilder
{
    void BuildPartA();  // 构建部件A
    void BuildPartB();  // 构建部件B
    Product GetProduct();  // 获取产品
}

// 具体建造者
public class ConcreteBuilder : IBuilder
{
    private Product _product = new Product();  // 产品实例

    // 构建部件A
    public void BuildPartA() => _product.Add("PartA");
    
    // 构建部件B
    public void BuildPartB() => _product.Add("PartB");
    
    // 获取产品并重置建造者
    public Product GetProduct()
    {
        var result = _product;  // 保存当前产品
        _product = new Product(); // 重置产品,为下一次构建准备
        return result;  // 返回构建好的产品
    }
}

// 使用示例
var builder = new ConcreteBuilder();  // 创建建造者
builder.BuildPartA();  // 构建部件A
builder.BuildPartB();  // 构建部件B
var product = builder.GetProduct();  // 获取最终产品
Console.WriteLine(product.ListParts());  // 显示产品部件

5. 原型模式 (Prototype)

目的:通过复制现有对象来创建新对象,而不是新建。

csharp 复制代码
// 抽象原型类
public abstract class Prototype
{
    public int Id { get; }  // 标识符
    
    protected Prototype(int id) => Id = id;  // 构造函数
    
    public abstract Prototype Clone();  // 克隆方法
}

// 具体原型类1
public class ConcretePrototype1 : Prototype
{
    public ConcretePrototype1(int id) : base(id) { }  // 调用父类构造函数
    
    // 实现克隆方法
    public override Prototype Clone() => new ConcretePrototype1(Id);
}

// 使用示例
var original = new ConcretePrototype1(1);  // 创建原始对象
var clone = original.Clone();  // 克隆对象
Console.WriteLine($"Original ID: {original.Id}, Clone ID: {clone.Id}");  // 比较ID

二、结构型模式(7种)

6. 适配器模式 (Adapter)

目的:将一个类的接口转换成客户希望的另一个接口。

csharp 复制代码
// 目标接口
public interface ITarget
{
    string GetRequest();  // 获取请求
}

// 需要适配的类
public class Adaptee
{
    public string GetSpecificRequest() => "Specific request";  // 特定请求方法
}

// 适配器类
public class Adapter : ITarget
{
    private readonly Adaptee _adaptee;  // 被适配对象
    
    public Adapter(Adaptee adaptee) => _adaptee = adaptee;  // 构造函数注入
    
    // 实现目标接口,适配被适配对象的方法
    public string GetRequest() => $"This is '{_adaptee.GetSpecificRequest()}'";
}

// 使用示例
Adaptee adaptee = new Adaptee();  // 创建被适配对象
ITarget target = new Adapter(adaptee);  // 创建适配器
Console.WriteLine(target.GetRequest());  // 通过适配器调用方法

7. 桥接模式 (Bridge)

目的:将抽象部分与其实现部分分离,使它们都可以独立变化。

csharp 复制代码
// 实现接口
public interface IImplementation
{
    string OperationImplementation();  // 实现操作
}

// 具体实现A
public class ConcreteImplementationA : IImplementation
{
    public string OperationImplementation() => "ConcreteImplementationA";  // 具体实现
}

// 抽象类
public abstract class Abstraction
{
    protected IImplementation _implementation;  // 实现引用
    
    // 构造函数注入实现
    protected Abstraction(IImplementation implementation) => _implementation = implementation;
    
    public abstract string Operation();  // 抽象操作
}

// 扩展抽象类
public class ExtendedAbstraction : Abstraction
{
    // 调用父类构造函数
    public ExtendedAbstraction(IImplementation implementation) : base(implementation) { }
    
    // 实现抽象操作
    public override string Operation() => $"Extended: {_implementation.OperationImplementation()}";
}

// 使用示例
IImplementation implementation = new ConcreteImplementationA();  // 创建具体实现
Abstraction abstraction = new ExtendedAbstraction(implementation);  // 创建抽象
Console.WriteLine(abstraction.Operation());  // 调用操作

8. 组合模式 (Composite)

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

csharp 复制代码
// 抽象组件
public abstract class Component
{
    public abstract string Operation();  // 抽象操作
    
    // 虚方法,默认抛出异常
    public virtual void Add(Component component) => throw new NotImplementedException();
    public virtual void Remove(Component component) => throw new NotImplementedException();
    public virtual bool IsComposite() => true;  // 默认是组合节点
}

// 叶子节点
public class Leaf : Component
{
    public override string Operation() => "Leaf";  // 叶子节点操作
    
    public override bool IsComposite() => false;  // 不是组合节点
}

// 组合节点
public class Composite : Component
{
    protected List<Component> _children = new List<Component>();  // 子组件列表
    
    // 添加子组件
    public override void Add(Component component) => _children.Add(component);
    
    // 移除子组件
    public override void Remove(Component component) => _children.Remove(component);
    
    // 组合节点操作,递归调用子组件操作
    public override string Operation()
    {
        var results = new List<string>();
        foreach (var child in _children)
            results.Add(child.Operation());
        return $"Branch({string.Join("+", results)})";  // 返回组合结果
    }
}

// 使用示例
var leaf1 = new Leaf();  // 创建叶子1
var leaf2 = new Leaf();  // 创建叶子2
var composite = new Composite();  // 创建组合节点
composite.Add(leaf1);  // 添加叶子1
composite.Add(leaf2);  // 添加叶子2
Console.WriteLine(composite.Operation());  // 执行组合操作

9. 装饰器模式 (Decorator)

目的:动态地给一个对象添加一些额外的职责。

csharp 复制代码
// 抽象组件
public abstract class Component
{
    public abstract string Operation();  // 抽象操作
}

// 具体组件
public class ConcreteComponent : Component
{
    public override string Operation() => "ConcreteComponent";  // 具体操作
}

// 抽象装饰器
public abstract class Decorator : Component
{
    protected Component _component;  // 被装饰组件
    
    // 构造函数注入组件
    public Decorator(Component component) => _component = component;
    
    // 委托给被装饰组件
    public override string Operation() => _component.Operation();
}

// 具体装饰器A
public class ConcreteDecoratorA : Decorator
{
    // 调用父类构造函数
    public ConcreteDecoratorA(Component component) : base(component) { }
    
    // 扩展操作
    public override string Operation() => $"ConcreteDecoratorA({base.Operation()})";
}

// 使用示例
Component component = new ConcreteComponent();  // 创建具体组件
Component decorated = new ConcreteDecoratorA(component);  // 创建装饰器
Console.WriteLine(decorated.Operation());  // 调用装饰后的操作

10. 外观模式 (Facade)

目的:为子系统中的一组接口提供一个一致的界面。

csharp 复制代码
// 子系统1
public class Subsystem1
{
    public string Operation1() => "Subsystem1: Ready!";  // 操作1
    public string OperationN() => "Subsystem1: Go!";  // 操作N
}

// 子系统2
public class Subsystem2
{
    public string Operation1() => "Subsystem2: Get ready!";  // 操作1
    public string OperationZ() => "Subsystem2: Fire!";  // 操作Z
}

// 外观类
public class Facade
{
    private Subsystem1 _subsystem1;  // 子系统1引用
    private Subsystem2 _subsystem2;  // 子系统2引用
    
    // 构造函数注入子系统
    public Facade(Subsystem1 s1, Subsystem2 s2)
    {
        _subsystem1 = s1;
        _subsystem2 = s2;
    }
    
    // 统一操作接口
    public string Operation()
    {
        var result = new List<string>();
        result.Add(_subsystem1.Operation1());  // 调用子系统1操作1
        result.Add(_subsystem2.Operation1());  // 调用子系统2操作1
        result.Add(_subsystem1.OperationN());  // 调用子系统1操作N
        result.Add(_subsystem2.OperationZ());  // 调用子系统2操作Z
        return string.Join("\n", result);  // 返回组合结果
    }
}

// 使用示例
var subsystem1 = new Subsystem1();  // 创建子系统1
var subsystem2 = new Subsystem2();  // 创建子系统2
var facade = new Facade(subsystem1, subsystem2);  // 创建外观
Console.WriteLine(facade.Operation());  // 通过外观调用操作

11. 享元模式 (Flyweight)

目的:运用共享技术有效地支持大量细粒度的对象。

csharp 复制代码
// 享元类
public class Flyweight
{
    private string _sharedState;  // 内部状态(共享)
    
    public Flyweight(string sharedState) => _sharedState = sharedState;  // 构造函数
    
    // 操作,接受外部状态
    public void Operation(string uniqueState) 
        => Console.WriteLine($"Shared: {_sharedState}, Unique: {uniqueState}");
}

// 享元工厂
public class FlyweightFactory
{
    private Dictionary<string, Flyweight> _flyweights = new Dictionary<string, Flyweight>();  // 享元缓存
    
    // 获取享元对象
    public Flyweight GetFlyweight(string key)
    {
        // 如果不存在则创建
        if (!_flyweights.ContainsKey(key))
            _flyweights[key] = new Flyweight(key);  // 创建新享元
        return _flyweights[key];  // 返回享元对象
    }
}

// 使用示例
var factory = new FlyweightFactory();  // 创建享元工厂
var flyweight1 = factory.GetFlyweight("shared1");  // 获取享元1
flyweight1.Operation("unique1");  // 使用享元1
var flyweight2 = factory.GetFlyweight("shared1");  // 获取享元2(共享同一个)
flyweight2.Operation("unique2");  // 使用享元2

12. 代理模式 (Proxy)

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

csharp 复制代码
// 主题接口
public interface ISubject
{
    void Request();  // 请求方法
}

// 真实主题
public class RealSubject : ISubject
{
    public void Request() => Console.WriteLine("RealSubject: Handling Request.");  // 真实处理
}

// 代理类
public class Proxy : ISubject
{
    private RealSubject _realSubject;  // 真实主题引用
    
    // 请求方法
    public void Request()
    {
        // 延迟初始化
        if (_realSubject == null)
            _realSubject = new RealSubject();  // 创建真实主题
        _realSubject.Request();  // 委托给真实主题
    }
}

// 使用示例
ISubject subject = new Proxy();  // 创建代理
subject.Request();  // 通过代理调用请求

三、行为型模式(11种)

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

目的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

csharp 复制代码
// 处理器接口
public interface IHandler
{
    IHandler SetNext(IHandler handler);  // 设置下一个处理器
    object Handle(object request);  // 处理请求
}

// 抽象处理器
public abstract class AbstractHandler : IHandler
{
    private IHandler _nextHandler;  // 下一个处理器
    
    // 设置下一个处理器
    public IHandler SetNext(IHandler handler)
    {
        _nextHandler = handler;
        return handler;  // 返回处理器,支持链式调用
    }
    
    // 处理请求,默认传递给下一个处理器
    public virtual object Handle(object request)
    {
        return _nextHandler?.Handle(request);  // 调用下一个处理器
    }
}

// 具体处理器:猴子处理器
public class MonkeyHandler : AbstractHandler
{
    // 处理请求
    public override object Handle(object request)
    {
        // 如果请求是香蕉,则处理
        if ((request as string) == "Banana")
            return $"Monkey: I'll eat the {request}.";  // 返回处理结果
        return base.Handle(request);  // 否则传递给下一个处理器
    }
}

// 使用示例
var monkey = new MonkeyHandler();  // 创建猴子处理器
var squirrel = new SquirrelHandler();  // 创建松鼠处理器
monkey.SetNext(squirrel);  // 设置责任链
Console.WriteLine(monkey.Handle("Banana"));  // 处理请求

14. 命令模式 (Command)

目的:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。

csharp 复制代码
// 命令接口
public interface ICommand
{
    void Execute();  // 执行命令
}

// 简单命令
public class SimpleCommand : ICommand
{
    private string _payload;  // 命令数据
    
    public SimpleCommand(string payload) => _payload = payload;  // 构造函数
    
    public void Execute() => Console.WriteLine($"SimpleCommand: {_payload}");  // 执行命令
}

// 调用者
public class Invoker
{
    private ICommand _onStart;  // 开始命令
    private ICommand _onFinish;  // 结束命令
    
    // 设置开始命令
    public void SetOnStart(ICommand command) => _onStart = command;
    
    // 设置结束命令
    public void SetOnFinish(ICommand command) => _onFinish = command;
    
    // 执行业务逻辑
    public void DoSomethingImportant()
    {
        _onStart?.Execute();  // 执行开始命令
        // 其他业务逻辑...
        _onFinish?.Execute();  // 执行结束命令
    }
}

// 使用示例
var invoker = new Invoker();  // 创建调用者
invoker.SetOnStart(new SimpleCommand("Say Hi!"));  // 设置开始命令
invoker.DoSomethingImportant();  // 执行业务逻辑

15. 解释器模式 (Interpreter)

目的:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

csharp 复制代码
// 抽象表达式
public interface IExpression
{
    bool Interpret(string context);  // 解释方法
}

// 终结符表达式
public class TerminalExpression : IExpression
{
    private string _data;  // 数据
    
    public TerminalExpression(string data) => _data = data;  // 构造函数
    
    // 解释上下文是否包含数据
    public bool Interpret(string context) => context.Contains(_data);
}

// 或表达式
public class OrExpression : IExpression
{
    private IExpression _expr1;  // 表达式1
    private IExpression _expr2;  // 表达式2
    
    // 构造函数
    public OrExpression(IExpression expr1, IExpression expr2)
    {
        _expr1 = expr1;
        _expr2 = expr2;
    }
    
    // 解释:表达式1或表达式2为真
    public bool Interpret(string context) 
        => _expr1.Interpret(context) || _expr2.Interpret(context);
}

// 使用示例
IExpression expr1 = new TerminalExpression("John");  // 创建终结符表达式1
IExpression expr2 = new TerminalExpression("Married");  // 创建终结符表达式2
IExpression orExpr = new OrExpression(expr1, expr2);  // 创建或表达式
Console.WriteLine(orExpr.Interpret("John is here")); // true,包含John

16. 迭代器模式 (Iterator)

目的:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

csharp 复制代码
// 迭代器接口
public interface IIterator
{
    bool HasNext();  // 是否有下一个元素
    object Next();  // 获取下一个元素
}

// 聚合接口
public interface IAggregate
{
    IIterator CreateIterator();  // 创建迭代器
}

// 具体聚合
public class ConcreteAggregate : IAggregate
{
    private List<object> _items = new List<object>();  // 元素列表
    
    // 创建迭代器
    public IIterator CreateIterator() => new ConcreteIterator(this);
    
    public int Count => _items.Count;  // 元素数量
    
    // 索引器
    public object this[int index]
    {
        get => _items[index];  // 获取元素
        set => _items.Insert(index, value);  // 设置元素
    }
}

// 具体迭代器
public class ConcreteIterator : IIterator
{
    private ConcreteAggregate _aggregate;  // 聚合对象
    private int _current = 0;  // 当前位置
    
    public ConcreteIterator(ConcreteAggregate aggregate) => _aggregate = aggregate;  // 构造函数
    
    // 检查是否有下一个元素
    public bool HasNext() => _current < _aggregate.Count;
    
    // 获取下一个元素
    public object Next() => _aggregate[_current++];
}

// 使用示例
var aggregate = new ConcreteAggregate();  // 创建聚合对象
aggregate[0] = "Item A";  // 添加元素A
aggregate[1] = "Item B";  // 添加元素B
var iterator = aggregate.CreateIterator();  // 创建迭代器
while (iterator.HasNext())  // 遍历元素
    Console.WriteLine(iterator.Next());  // 输出元素

17. 中介者模式 (Mediator)

目的:用一个中介对象来封装一系列的对象交互。

csharp 复制代码
// 中介者接口
public interface IMediator
{
    void Notify(object sender, string ev);  // 通知方法
}

// 具体中介者
public class ConcreteMediator : IMediator
{
    public Component1 Component1 { get; set; }  // 组件1
    public Component2 Component2 { get; set; }  // 组件2
    
    // 处理通知
    public void Notify(object sender, string ev)
    {
        if (ev == "A")  // 事件A
        {
            Console.WriteLine("Mediator reacts on A and triggers:");
            Component2.DoC();  // 触发组件2的操作C
        }
        else if (ev == "D")  // 事件D
        {
            Console.WriteLine("Mediator reacts on D and triggers:");
            Component1.DoB();  // 触发组件1的操作B
        }
    }
}

// 基础组件
public class BaseComponent
{
    protected IMediator _mediator;  // 中介者引用
    
    public BaseComponent(IMediator mediator = null) => _mediator = mediator;  // 构造函数
    
    public void SetMediator(IMediator mediator) => _mediator = mediator;  // 设置中介者
}

// 组件1
public class Component1 : BaseComponent
{
    public void DoA()
    {
        Console.WriteLine("Component 1 does A.");  // 执行操作A
        _mediator.Notify(this, "A");  // 通知中介者
    }
    public void DoB()
    {
        Console.WriteLine("Component 1 does B.");  // 执行操作B
        _mediator.Notify(this, "B");  // 通知中介者
    }
}

// 使用示例
var mediator = new ConcreteMediator();  // 创建中介者
var c1 = new Component1(mediator);  // 创建组件1
var c2 = new Component2(mediator);  // 创建组件2
mediator.Component1 = c1;  // 设置组件1
mediator.Component2 = c2;  // 设置组件2
c1.DoA();  // 组件1执行操作A

18. 备忘录模式 (Memento)

目的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

csharp 复制代码
// 备忘录类
public class Memento
{
    private string _state;  // 状态
    
    public Memento(string state) => _state = state;  // 构造函数
    
    public string GetState() => _state;  // 获取状态
}

// 原发器
public class Originator
{
    private string _state;  // 内部状态
    
    // 设置状态
    public void SetState(string state)
    {
        Console.WriteLine($"Setting state to {state}");  // 输出状态设置
        _state = state;
    }
    
    // 保存状态到备忘录
    public Memento Save() => new Memento(_state);
    
    // 从备忘录恢复状态
    public void Restore(Memento memento)
    {
        _state = memento.GetState();  // 恢复状态
        Console.WriteLine($"State restored to: {_state}");  // 输出状态恢复
    }
}

// 负责人
public class Caretaker
{
    private List<Memento> _mementos = new List<Memento>();  // 备忘录列表
    private Originator _originator;  // 原发器引用
    
    public Caretaker(Originator originator) => _originator = originator;  // 构造函数
    
    public void Backup() => _mementos.Add(_originator.Save());  // 备份状态
    
    // 撤销操作
    public void Undo()
    {
        if (_mementos.Count == 0) return;  // 没有备忘录可恢复
        var memento = _mementos.Last();  // 获取最后一个备忘录
        _mementos.Remove(memento);  // 从列表中移除
        _originator.Restore(memento);  // 恢复状态
    }
}

// 使用示例
var originator = new Originator();  // 创建原发器
var caretaker = new Caretaker(originator);  // 创建负责人
originator.SetState("State #1");  // 设置状态1
caretaker.Backup();  // 备份状态
originator.SetState("State #2");  // 设置状态2
caretaker.Undo();  // 撤销到状态1

19. 观察者模式 (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
{
    public int State { get; set; }  // 状态
    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);  // 调用观察者更新方法
    }
    
    // 业务逻辑方法
    public void SomeBusinessLogic()
    {
        State = new Random().Next(0, 10);  // 改变状态
        Notify();  // 通知观察者
    }
}

// 具体观察者
public class ConcreteObserver : IObserver
{
    // 更新方法
    public void Update(ISubject subject)
    {
        // 状态小于3时反应
        if ((subject as Subject).State < 3)
            Console.WriteLine("ConcreteObserver: Reacted to the event.");
    }
}

// 使用示例
var subject = new Subject();  // 创建主题
var observer = new ConcreteObserver();  // 创建观察者
subject.Attach(observer);  // 附加观察者
subject.SomeBusinessLogic();  // 执行业务逻辑,触发通知

20. 状态模式 (State)

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

csharp 复制代码
// 上下文类
public class Context
{
    private State _state;  // 当前状态
    
    public Context(State state) => TransitionTo(state);  // 构造函数
    
    // 转换状态
    public void TransitionTo(State state)
    {
        Console.WriteLine($"Context: Transition to {state.GetType().Name}");  // 输出状态转换
        _state = state;  // 设置新状态
        _state.SetContext(this);  // 设置状态的上下文
    }
    
    public void Request1() => _state.Handle1();  // 请求1
    public void Request2() => _state.Handle2();  // 请求2
}

// 抽象状态
public abstract class State
{
    protected Context _context;  // 上下文引用
    
    public void SetContext(Context context) => _context = context;  // 设置上下文
    
    public abstract void Handle1();  // 处理请求1
    public abstract void Handle2();  // 处理请求2
}

// 具体状态A
public class ConcreteStateA : State
{
    // 处理请求1
    public override void Handle1()
    {
        Console.WriteLine("ConcreteStateA handles request1.");  // 处理请求
        Console.WriteLine("ConcreteStateA wants to change the state of the context.");  // 状态转换提示
        _context.TransitionTo(new ConcreteStateB());  // 转换到状态B
    }
    
    // 处理请求2
    public override void Handle2() => Console.WriteLine("ConcreteStateA handles request2.");
}

// 使用示例
var context = new Context(new ConcreteStateA());  // 创建上下文,初始状态A
context.Request1();  // 发送请求1,触发状态转换
context.Request2();  // 发送请求2

21. 策略模式 (Strategy)

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

csharp 复制代码
// 策略接口
public interface IStrategy
{
    object DoAlgorithm(object data);  // 执行算法
}

// 具体策略A
public class ConcreteStrategyA : IStrategy
{
    // 执行算法:对字符串列表排序
    public object DoAlgorithm(object data)
    {
        var list = data as List<string>;  // 转换数据类型
        list.Sort();  // 排序
        return list;  // 返回结果
    }
}

// 上下文类
public class Context
{
    private IStrategy _strategy;  // 当前策略
    
    public Context(IStrategy strategy) => _strategy = strategy;  // 构造函数
    
    // 设置策略
    public void SetStrategy(IStrategy strategy) => _strategy = strategy;
    
    // 执行业务逻辑
    public void DoSomeBusinessLogic()
    {
        var result = _strategy.DoAlgorithm(new List<string> { "a", "b", "c" });  // 执行策略算法
        Console.WriteLine(string.Join(",", result));  // 输出结果
    }
}

// 使用示例
var context = new Context(new ConcreteStrategyA());  // 创建上下文,使用策略A
context.DoSomeBusinessLogic();  // 执行业务逻辑
context.SetStrategy(new ConcreteStrategyB());  // 切换策略B
context.DoSomeBusinessLogic();  // 执行业务逻辑

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

目的:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

csharp 复制代码
// 抽象类
public abstract class AbstractClass
{
    // 模板方法
    public void TemplateMethod()
    {
        this.BaseOperation1();  // 基础操作1
        this.RequiredOperations1();  // 必需操作1
        this.BaseOperation2();  // 基础操作2
        this.Hook1();  // 钩子方法1
    }
    
    // 基础操作1
    protected void BaseOperation1() 
        => Console.WriteLine("AbstractClass says: I am doing the bulk of the work");
    
    // 基础操作2
    protected void BaseOperation2() 
        => Console.WriteLine("AbstractClass says: But I let subclasses override some operations");
    
    protected abstract void RequiredOperations1();  // 抽象方法,子类必须实现
    protected virtual void Hook1() { }  // 钩子方法,子类可选重写
}

// 具体类1
public class ConcreteClass1 : AbstractClass
{
    // 实现必需操作1
    protected override void RequiredOperations1() 
        => Console.WriteLine("ConcreteClass1 says: Implemented Operation1");
}

// 使用示例
AbstractClass abstractClass = new ConcreteClass1();  // 创建具体类实例
abstractClass.TemplateMethod();  // 调用模板方法

23. 访问者模式 (Visitor)

目的:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

csharp 复制代码
// 组件接口
public interface IComponent
{
    void Accept(IVisitor visitor);  // 接受访问者
}

// 具体组件A
public class ConcreteComponentA : IComponent
{
    // 接受访问者
    public void Accept(IVisitor visitor) => visitor.VisitConcreteComponentA(this);
    
    // 组件A的专属方法
    public string ExclusiveMethodOfConcreteComponentA() => "A";
}

// 访问者接口
public interface IVisitor
{
    void VisitConcreteComponentA(ConcreteComponentA element);  // 访问组件A
    void VisitConcreteComponentB(ConcreteComponentB element);  // 访问组件B
}

// 具体访问者1
public class ConcreteVisitor1 : IVisitor
{
    // 访问组件A
    public void VisitConcreteComponentA(ConcreteComponentA element)
    {
        Console.WriteLine($"{element.ExclusiveMethodOfConcreteComponentA()} + ConcreteVisitor1");  // 组合输出
    }
    
    // 访问组件B
    public void VisitConcreteComponentB(ConcreteComponentB element)
    {
        Console.WriteLine($"{element.SpecialMethodOfConcreteComponentB()} + ConcreteVisitor1");  // 组合输出
    }
}

// 使用示例
var components = new List<IComponent>  // 创建组件列表
{
    new ConcreteComponentA(),  // 组件A
    new ConcreteComponentB()   // 组件B
};

var visitor1 = new ConcreteVisitor1();  // 创建访问者
foreach (var component in components)  // 遍历所有组件
    component.Accept(visitor1);  // 接受访问者访问

总结

这23种设计模式为解决特定问题提供了经过验证的解决方案。在实际开发中,应根据具体场景选择合适的设计模式,而不是为了使用模式而使用模式。设计模式的目标是提高代码的可维护性、可扩展性和可重用性。

相关推荐
Mr_WangAndy2 小时前
C++设计模式_结构型模式_适配器模式Adapter
c++·设计模式·适配器模式·c++设计模式
bkspiderx2 小时前
C++设计模式之结构型模式:代理模式(Proxy)
c++·设计模式·代理模式
1710orange2 小时前
java设计模式:适配器模式
java·设计模式·适配器模式
CAE虚拟与现实3 小时前
PyQt和PySide中使用Qt Designer
开发语言·qt·pyqt·qt designer·pyside
Paul_09203 小时前
golang面经——channel模块
开发语言
Cauhele浅能3 小时前
【嵌入式C快捷键设计】表驱动法实现
c语言·设计模式
赵谨言3 小时前
基于python数据挖据的教学监控系统的设计与应用
开发语言·经验分享·python
润 下3 小时前
C语言——深入理解函数声明定义和调用访问
c语言·开发语言·经验分享·笔记·程序人生·其他
一只自律的鸡3 小时前
【python】从Hello World到数据类型
开发语言·python