设计模式笔记

23 种设计模式

创建型模式(Creational Patterns)

1. 单例模式(Singleton)

定义:保证一个类只有一个实例,并提供一个全局访问点。

通俗理解:就像全国只有一个身份证号码,每个人都唯一,不能重复。

适用场景:只需要一个对象的场合,如配置管理器、日志对象。

// 单例模式示例
public sealed class Singleton
{
    private static readonly Singleton _instance = new Singleton();
    public string Config { get; set; } = "默认配置";
    private Singleton() { }
    public static Singleton Instance => _instance;
}

// 调用示例
var obj1 = Singleton.Instance;
var obj2 = Singleton.Instance;
obj1.Config = "新配置";
Console.WriteLine(obj2.Config); // 输出:新配置

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

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

通俗理解:就像开工厂生产产品,不同工厂生产不同产品。

适用场景:当一个类不知道它所需要创建的对象的类时。

// 工厂方法模式示例
interface IProduct
{
    void Show();
}

class ProductA : IProduct
{
    public void Show() => Console.WriteLine("我是产品A");
}

class ProductB : IProduct
{
    public void Show() => Console.WriteLine("我是产品B");
}

abstract class Creator
{
    public abstract IProduct FactoryMethod();
}

class CreatorA : Creator
{
    public override IProduct FactoryMethod() => new ProductA();
}

class CreatorB : Creator
{
    public override IProduct FactoryMethod() => new ProductB();
}

// 调用示例
Creator factory = new CreatorA();
IProduct product = factory.FactoryMethod();
product.Show(); // 输出:我是产品A

factory = new CreatorB();
product = factory.FactoryMethod();
product.Show(); // 输出:我是产品B

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

定义:提供一个创建一系列相关或相互依赖对象的接口。

通俗理解:像宜家家居套餐,一次性买齐风格统一的家具。

适用场景:需要创建一系列相关产品对象时。

// 抽象工厂模式示例
interface IButton
{
    void Paint();
}

interface ITextBox
{
    void Show();
}

class WinButton : IButton
{
    public void Paint() => Console.WriteLine("Windows按钮");
}

class MacButton : IButton
{
    public void Paint() => Console.WriteLine("Mac按钮");
}

class WinTextBox : ITextBox
{
    public void Show() => Console.WriteLine("Windows文本框");
}

class MacTextBox : ITextBox
{
    public void Show() => Console.WriteLine("Mac文本框");
}

interface IGUIFactory
{
    IButton CreateButton();
    ITextBox CreateTextBox();
}

class WinFactory : IGUIFactory
{
    public IButton CreateButton() => new WinButton();
    public ITextBox CreateTextBox() => new WinTextBox();
}

class MacFactory : IGUIFactory
{
    public IButton CreateButton() => new MacButton();
    public ITextBox CreateTextBox() => new MacTextBox();
}

// 调用示例
IGUIFactory factory = new WinFactory();
factory.CreateButton().Paint(); // 输出:Windows按钮
factory.CreateTextBox().Show(); // 输出:Windows文本框

factory = new MacFactory();
factory.CreateButton().Paint(); // 输出:Mac按钮
factory.CreateTextBox().Show(); // 输出:Mac文本框

4. 建造者模式(Builder)

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

通俗理解:像搭积木,先搭框架再装饰细节。

适用场景:需要构建复杂对象时。

// 建造者模式示例
class Meal
{
    public List<string> Parts = new();
    public void Show() => Console.WriteLine(string.Join(", ", Parts));
}

interface IMealBuilder
{
    void BuildMain();
    void BuildDrink();
    Meal GetMeal();
}

class ChineseMealBuilder : IMealBuilder
{
    private Meal _meal = new Meal();
    public void BuildMain() => _meal.Parts.Add("米饭");
    public void BuildDrink() => _meal.Parts.Add("豆浆");
    public Meal GetMeal() => _meal;
}

class WesternMealBuilder : IMealBuilder
{
    private Meal _meal = new Meal();
    public void BuildMain() => _meal.Parts.Add("牛排");
    public void BuildDrink() => _meal.Parts.Add("红酒");
    public Meal GetMeal() => _meal;
}

class Waiter
{
    public void Construct(IMealBuilder builder)
    {
        builder.BuildMain();
        builder.BuildDrink();
    }
}

// 调用示例
Waiter waiter = new Waiter();
IMealBuilder builder = new ChineseMealBuilder();
waiter.Construct(builder);
builder.GetMeal().Show(); // 输出:米饭, 豆浆

builder = new WesternMealBuilder();
waiter.Construct(builder);
builder.GetMeal().Show(); // 输出:牛排, 红酒

5. 原型模式(Prototype)

定义:通过复制已有实例创建新对象。

通俗理解:像复印文件,快速复制出一份一模一样的。

适用场景:需要大量相同或相似对象时。

// 原型模式示例
class Resume : ICloneable
{
    public string Name;
    public Resume(string name) { Name = name; }
    public object Clone() => new Resume(Name);
}

// 调用示例
Resume r1 = new Resume("小明");
Resume r2 = (Resume)r1.Clone();
Console.WriteLine(r2.Name); // 输出:小明

结构型模式(Structural Patterns)

6. 适配器模式(Adapter)

定义:将一个接口转换成客户端期望的另一个接口。

通俗理解:像插头转换器,让不同国家的插头都能用。

适用场景:系统需要使用现有的类,但接口不兼容时。

// 适配器模式示例
interface ITarget
{
    void Request();
}

class Adaptee
{
    public void SpecificRequest() => Console.WriteLine("特殊请求");
}

class Adapter : ITarget
{
    private Adaptee _adaptee = new Adaptee();
    public void Request() => _adaptee.SpecificRequest();
}

// 调用示例
ITarget target = new Adapter();
target.Request(); // 输出:特殊请求

7. 桥接模式(Bridge)

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

通俗理解:像遥控器和电视,遥控器控制不同品牌的电视。

适用场景:抽象和实现都需要扩展时。

// 桥接模式示例
interface ITV
{
    void Play();
}

class SonyTV : ITV
{
    public void Play() => Console.WriteLine("播放Sony电视");
}

class TCLTV : ITV
{
    public void Play() => Console.WriteLine("播放TCL电视");
}

abstract class RemoteControl
{
    protected ITV tv;
    public RemoteControl(ITV tv) { this.tv = tv; }
    public abstract void Operate();
}

class ConcreteRemote : RemoteControl
{
    public ConcreteRemote(ITV tv) : base(tv) { }
    public override void Operate() => tv.Play();
}

// 调用示例
RemoteControl remote = new ConcreteRemote(new SonyTV());
remote.Operate(); // 输出:播放Sony电视

remote = new ConcreteRemote(new TCLTV());
remote.Operate(); // 输出:播放TCL电视

8. 组合模式(Composite)

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

通俗理解:像公司组织架构,部门下有小组,小组下有员工。

适用场景:需要表示对象的部分-整体层次结构时。

// 组合模式示例
abstract class Company
{
    public string Name;
    public Company(string name) { Name = name; }
    public abstract void Display(int depth);
}

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

class CompositeCompany : Company
{
    private List<Company> children = new();
    public CompositeCompany(string name) : base(name) { }
    public void Add(Company c) => children.Add(c);
    public override void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + Name);
        foreach (var c in children) c.Display(depth + 2);
    }
}

// 调用示例
CompositeCompany root = new CompositeCompany("总公司");
root.Add(new Department("人事部"));
CompositeCompany branch = new CompositeCompany("分公司");
branch.Add(new Department("财务部"));
root.Add(branch);
root.Display(1);

9. 装饰器模式(Decorator)

定义:动态地给对象添加职责。

通俗理解:像给手机加壳、贴膜,功能增强但本体不变。

适用场景:需要动态扩展对象功能时。

// 装饰器模式示例
interface ICoffee
{
    string GetDescription();
}

class SimpleCoffee : ICoffee
{
    public string GetDescription() => "黑咖啡";
}

class MilkDecorator : ICoffee
{
    private ICoffee _coffee;
    public MilkDecorator(ICoffee coffee) { _coffee = coffee; }
    public string GetDescription() => _coffee.GetDescription() + "+牛奶";
}

class SugarDecorator : ICoffee
{
    private ICoffee _coffee;
    public SugarDecorator(ICoffee coffee) { _coffee = coffee; }
    public string GetDescription() => _coffee.GetDescription() + "+糖";
}

// 调用示例
ICoffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
Console.WriteLine(coffee.GetDescription()); // 输出:黑咖啡+牛奶+糖

10. 外观模式(Facade)

定义:为子系统中的一组接口提供统一的接口。

通俗理解:像万能遥控器,一键控制多个家电。

适用场景:为复杂子系统提供简单接口时。

// 外观模式示例
class Light
{
    public void On() => Console.WriteLine("开灯");
}

class TV
{
    public void On() => Console.WriteLine("开电视");
}

class Facade
{
    private Light _light = new Light();
    private TV _tv = new TV();
    public void MovieMode()
    {
        _light.On();
        _tv.On();
    }
}

// 调用示例
Facade facade = new Facade();
facade.MovieMode(); // 输出:开灯\n开电视

11. 享元模式(Flyweight)

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

通俗理解:像汉字字形库,常用字只存一份,节省内存。

适用场景:大量对象中有可共享部分时。

// 享元模式示例
class ChessPiece
{
    public string Color;
    public ChessPiece(string color) { Color = color; }
    public void Display(int x, int y) => Console.WriteLine($"{Color}棋子在({x},{y})");
}

class ChessFactory
{
    private Dictionary<string, ChessPiece> _pool = new();
    public ChessPiece GetPiece(string color)
    {
        if (!_pool.ContainsKey(color)) _pool[color] = new ChessPiece(color);
        return _pool[color];
    }
}

// 调用示例
ChessFactory factory = new ChessFactory();
ChessPiece black1 = factory.GetPiece("黑");
ChessPiece black2 = factory.GetPiece("黑");
Console.WriteLine(object.ReferenceEquals(black1, black2)); // 输出:True
black1.Display(1, 2);

12. 代理模式(Proxy)

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

通俗理解:像明星经纪人,粉丝不能直接联系明星,要通过经纪人。

适用场景:需要为对象提供访问控制时。

// 代理模式示例
interface IStar
{
    void Meet();
}

class RealStar : IStar
{
    public void Meet() => Console.WriteLine("明星见粉丝");
}

class StarProxy : IStar
{
    private RealStar _star = new RealStar();
    public void Meet()
    {
        Console.WriteLine("经纪人安排见面");
        _star.Meet();
    }
}

// 调用示例
IStar star = new StarProxy();
star.Meet(); // 输出:经纪人安排见面\n明星见粉丝

行为型模式(Behavioral Patterns)

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

定义:使多个对象都有机会处理请求,避免请求的发送者和接收者耦合。

通俗理解:像公司请假流程,先找组长批,组长批不了再找经理。

适用场景:有多个对象可以处理同一请求时。

// 责任链模式示例
abstract class Approver
{
    protected Approver Next;
    public void SetNext(Approver next) { Next = next; }
    public abstract void Handle(int days);
}

class Leader : Approver
{
    public override void Handle(int days)
    {
        if (days <= 1) Console.WriteLine("组长批准");
        else if (Next != null) Next.Handle(days);
    }
}

class Manager : Approver
{
    public override void Handle(int days)
    {
        if (days <= 3) Console.WriteLine("经理批准");
        else if (Next != null) Next.Handle(days);
    }
}

// 调用示例
Approver leader = new Leader();
Approver manager = new Manager();
leader.SetNext(manager);
leader.Handle(1); // 输出:组长批准
leader.Handle(2); // 输出:经理批准

14. 命令模式(Command)

定义:将请求封装为对象,从而让你使用不同的请求、队列或日志参数化其他对象。

通俗理解:像点外卖,点单(命令)后,骑手(执行者)去完成。

适用场景:需要将操作请求、撤销、排队等功能封装时。

// 命令模式示例
interface ICommand
{
    void Execute();
}

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

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

class Remote
{
    private ICommand _command;
    public void SetCommand(ICommand command) { _command = command; }
    public void PressButton() { _command.Execute(); }
}

// 调用示例
Light light = new Light();
ICommand command = new LightOnCommand(light);
Remote remote = new Remote();
remote.SetCommand(command);
remote.PressButton(); // 输出:开灯

15. 解释器模式(Interpreter)

定义:给定一种语言,定义它的文法的一种表示,并定义一个解释器。

通俗理解:像计算器,输入表达式自动计算结果。

适用场景:需要解释执行某种语法规则时。

// 解释器模式示例
interface IExpression
{
    int Interpret();
}

class Number : IExpression
{
    private int _value;
    public Number(int value) { _value = value; }
    public int Interpret() => _value;
}

class Add : IExpression
{
    private IExpression _left, _right;
    public Add(IExpression left, IExpression right) { _left = left; _right = right; }
    public int Interpret() => _left.Interpret() + _right.Interpret();
}

// 调用示例
IExpression expr = new Add(new Number(1), new Number(2));
Console.WriteLine(expr.Interpret()); // 输出:3

16. 迭代器模式(Iterator)

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

通俗理解:像翻书,一页一页往下看。

适用场景:需要遍历集合对象时。

// 迭代器模式示例
class MyCollection
{
    private List<string> _items = new() { "A", "B" };
    public IEnumerator<string> GetEnumerator() => _items.GetEnumerator();
}

// 调用示例
MyCollection collection = new MyCollection();
foreach (var item in collection.GetEnumerator())
    Console.WriteLine(item); // 输出:A\nB

17. 中介者模式(Mediator)

定义:用一个中介对象封装一系列对象之间的交互。

通俗理解:像微信群,大家不直接私聊,而是通过群(中介)沟通。

适用场景:对象之间存在复杂引用关系时。

// 中介者模式示例
class ChatRoom
{
    public static void ShowMessage(string user, string message)
    {
        Console.WriteLine($"{user}说: {message}");
    }
}

class User
{
    public string Name;
    public User(string name) { Name = name; }
    public void Send(string message)
    {
        ChatRoom.ShowMessage(Name, message);
    }
}

// 调用示例
User tom = new User("Tom");
User jerry = new User("Jerry");
tom.Send("你好"); // 输出:Tom说: 你好
jerry.Send("Hi"); // 输出:Jerry说: Hi

18. 备忘录模式(Memento)

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

通俗理解:像游戏存档,随时保存和恢复进度。

适用场景:需要保存和恢复对象历史状态时。

// 备忘录模式示例
class Memento
{
    public string State;
    public Memento(string s) { State = s; }
}

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

// 调用示例
Originator originator = new Originator();
originator.State = "状态1";
Memento memento = originator.Save();
originator.State = "状态2";
originator.Restore(memento);
Console.WriteLine(originator.State); // 输出:状态1

19. 观察者模式(Observer)

定义:对象间一对多依赖,一个对象状态变化,所有依赖者都会收到通知。

通俗理解:像微信公众号,推送新消息所有粉丝都能收到。

适用场景:一个对象变化需要通知其他对象时。

// 观察者模式示例
interface IObserver
{
    void Update(string msg);
}

class Subscriber : IObserver
{
    public void Update(string msg) => Console.WriteLine($"收到消息: {msg}");
}

class Publisher
{
    private List<IObserver> observers = new();
    public void Add(IObserver o) => observers.Add(o);
    public void Notify(string msg)
    {
        foreach (var o in observers) o.Update(msg);
    }
}

// 调用示例
Publisher pub = new Publisher();
IObserver sub = new Subscriber();
pub.Add(sub);
pub.Notify("新内容"); // 输出:收到消息: 新内容

20. 状态模式(State)

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

通俗理解:像红绿灯,灯变色后交通规则也变。

适用场景:对象行为依赖于状态变化时。

// 状态模式示例
interface IState
{
    void Handle();
}

class RedState : IState
{
    public void Handle() => Console.WriteLine("红灯停");
}

class GreenState : IState
{
    public void Handle() => Console.WriteLine("绿灯行");
}

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

// 调用示例
Context context = new Context();
context.State = new RedState();
context.Request(); // 输出:红灯停
context.State = new GreenState();
context.Request(); // 输出:绿灯行

21. 策略模式(Strategy)

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

通俗理解:像出行方式,打车、骑车、步行,随时切换。

适用场景:需要在多种算法中选择时。

// 策略模式示例
interface IStrategy
{
    int Calculate(int a, int b);
}

class AddStrategy : IStrategy
{
    public int Calculate(int a, int b) => a + b;
}

class SubStrategy : IStrategy
{
    public int Calculate(int a, int b) => a - b;
}

class Calculator
{
    public IStrategy Strategy;
    public int Execute(int a, int b) => Strategy.Calculate(a, b);
}

// 调用示例
Calculator calc = new Calculator();
calc.Strategy = new AddStrategy();
Console.WriteLine(calc.Execute(1, 2)); // 输出:3
calc.Strategy = new SubStrategy();
Console.WriteLine(calc.Execute(5, 3)); // 输出:2

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

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

通俗理解:像做饭流程,先洗菜再炒菜,具体怎么洗炒由厨师决定。

适用场景:多个子类有相同方法结构但实现不同。

// 模板方法模式示例
abstract class Cook
{
    public void MakeDish()
    {
        Wash();
        CookMain();
        Serve();
    }
    protected abstract void CookMain();
    private void Wash() => Console.WriteLine("洗菜");
    private void Serve() => Console.WriteLine("上菜");
}

class FriedRice : Cook
{
    protected override void CookMain() => Console.WriteLine("炒饭");
}

// 调用示例
Cook cook = new FriedRice();
cook.MakeDish(); // 输出:洗菜\n炒饭\n上菜

23. 访问者模式(Visitor)

定义:表示一个作用于某对象结构中的各元素的操作。

通俗理解:像快递员上门收件,不同快递员对包裹有不同处理方式。

适用场景:需要对一组对象进行多种操作时。

// 访问者模式示例
interface IVisitor
{
    void Visit(Book book);
}

class Book
{
    public string Name;
    public Book(string name) { Name = name; }
    public void Accept(IVisitor visitor) => visitor.Visit(this);
}

class PriceVisitor : IVisitor
{
    public void Visit(Book book) => Console.WriteLine($"{book.Name}定价100元");
}

// 调用示例
Book book = new Book("设计模式");
IVisitor visitor = new PriceVisitor();
book.Accept(visitor); // 输出:设计模式定价100元

总结:设计模式对比表

模式名称 实用度 复杂度 优点 缺点 常见场景 现实类比
单例 ★★★★★ 全局唯一、节省资源 线程安全需注意 配置、日志 身份证号
工厂方法 ★★★★☆ ★★ 解耦创建与使用 类数量增多 对象创建灵活 汽车工厂
抽象工厂 ★★★★☆ ★★★ 产品族一致、易扩展 新增产品族难 一系列相关产品 家具套餐
建造者 ★★★☆☆ ★★★ 分步构建、灵活 结构复杂 复杂对象组装 盖房子
原型模式 ★★★☆☆ ★★ 快速复制、无需new 深拷贝复杂 批量相似对象 复印文件
适配器 ★★★★☆ ★★ 兼容性强、复用旧代码 可能影响性能 接口转换 插头转换器
桥接模式 ★★★☆☆ ★★★ 抽象与实现分离 设计复杂 多维度扩展 遥控器与电视
组合模式 ★★★★☆ ★★★ 层级结构清晰 管理复杂 树形结构 公司组织架构
装饰器 ★★★★☆ ★★★ 动态扩展功能 多层装饰难维护 功能增强 手机壳
外观模式 ★★★★☆ 简化接口、降低耦合 不易细粒度控制 子系统封装 万能遥控器
享元模式 ★★★☆☆ ★★★★ 节省内存 逻辑复杂 大量细粒度对象 汉字字形库
代理模式 ★★★★☆ ★★ 控制访问、增强功能 增加间接层 远程/安全控制 经纪人
责任链 ★★★★☆ ★★★ 请求灵活传递 调试困难 审批流、日志处理 请假流程
命令模式 ★★★☆☆ ★★★ 请求封装、可撤销 类增多 操作记录、事务 点外卖
解释器 ★★☆☆☆ ★★★★ 易扩展语法 效率低 表达式计算 计算器
迭代器 ★★★★☆ 统一遍历接口 仅适合线性结构 集合遍历 翻书
中介者 ★★★☆☆ ★★★ 降低耦合 中介者复杂 多对象交互 微信群
备忘录 ★★★☆☆ ★★ 状态恢复 占用资源 撤销、恢复 游戏存档
观察者 ★★★★★ ★★ 解耦通知 可能有性能问题 事件通知 微信公众号
状态模式 ★★★☆☆ ★★★ 状态切换灵活 状态类增多 状态驱动行为 红绿灯
策略模式 ★★★★☆ ★★ 算法可切换 客户端需知策略 多算法选择 出行方式
模板方法 ★★★★☆ ★★ 复用流程、易扩展 不灵活 固定流程 做饭流程
访问者 ★★☆☆☆ ★★★★ 新操作易扩展 结构变动难 多操作对象结构 快递员收件

注:实用度和复杂度为主观评价,仅供参考。

posted @ 2025-06-05 18:56  Ar4te  阅读(12)  评论(0)    收藏  举报