23 种设计模式分类与核心解析

45 阅读16分钟

在软件工程中,设计模式(Design Pattern) 是在特定场景下反复实践、被验证有效的通用设计方案。它不是可直接粘贴的代码片段,而是解决特定问题的设计思想与代码结构模板,是面试、日常开发、系统设计的核心知识点。

GoF(Gamma 等 4 位作者)提出的 23 种经典设计模式,按照解决问题的核心关注点,可清晰分为三大类,核心定位如下:

分类核心关注点设计目标
创建型对象如何创建解耦“对象创建”与“对象使用”
行为型对象如何协作、职责如何分配规范交互逻辑,降低协作复杂度
结构型类/对象如何组合优化结构,降低耦合,提升扩展

一、创建型设计模式(5 种)

核心目标:解耦“对象的创建”和“对象的使用” 避免直接 new 对象导致的耦合过高、创建逻辑混乱问题,让对象创建更灵活、可扩展。


1️⃣ 单例模式(Singleton)

设计意图:确保一个类在整个系统中仅有唯一实例,并提供全局统一的访问入口。 典型场景

  • 全局配置管理器(如 AppSettings 单例)
  • 日志组件(避免多实例写日志冲突)
  • 缓存对象(保证缓存数据一致性)
// 饿汉式(线程安全,推荐简单场景使用)
public sealed class Singleton
{
    // 静态初始化,CLR 保证线程安全
    private static readonly Singleton _instance = new Singleton();
    
    // 私有构造函数,禁止外部实例化
    private Singleton() { }
    
    // 全局访问点
    public static Singleton Instance => _instance;

    // 示例方法:验证单例唯一性
    public void DoSomething() => Console.WriteLine("单例对象执行操作");
}

// 调用示例
// var singleton1 = Singleton.Instance;
// var singleton2 = Singleton.Instance;
// Console.WriteLine(singleton1 == singleton2); // 输出:True

2️⃣ 简单工厂模式(Simple Factory)

设计意图:由一个工厂类封装所有对象的创建逻辑,调用方只需传入参数,无需关心对象的具体创建过程。 典型场景

  • 业务层创建不同类型的业务对象(如不同支付方式:微信/支付宝)
  • 基础组件创建不同格式的解析器(JSON/XML)
// 抽象产品接口
public interface ICar
{
    void Drive(); // 产品核心行为
}

// 具体产品:宝马
public class Bmw : ICar
{
    public void Drive() => Console.WriteLine("驾驶宝马汽车");
}

// 具体产品:奔驰
public class Benz : ICar
{
    public void Drive() => Console.WriteLine("驾驶奔驰汽车");
}

// 工厂类:封装创建逻辑
public class CarFactory
{
    // 根据参数创建不同产品
    public static ICar CreateCar(string carType)
    {
        return carType.ToUpper() switch
        {
            "BMW" => new Bmw(),
            "BENZ" => new Benz(),
            _ => throw new NotSupportedException($"不支持创建{carType}类型的汽车")
        };
    }
}

// 调用示例
// ICar car = CarFactory.CreateCar("BMW");
// car.Drive(); // 输出:驾驶宝马汽车

3️⃣ 工厂方法模式(Factory Method)

设计意图:将对象创建延迟到子类实现,每个子类对应一种产品创建,符合开闭原则(新增产品无需修改原有代码)。 典型场景

  • 电商系统:不同商家对应不同的订单工厂(京东订单/淘宝订单)
  • 框架扩展:自定义插件的创建(如 EF Core 不同数据库的上下文工厂)
// 抽象产品
public interface ICar
{
    void Drive();
}

// 具体产品:宝马
public class Bmw : ICar
{
    public void Drive() => Console.WriteLine("驾驶宝马汽车");
}

// 抽象工厂:定义创建产品的接口
public interface ICarFactory
{
    ICar CreateCar(); // 工厂方法
}

// 具体工厂:宝马工厂(负责创建宝马)
public class BmwFactory : ICarFactory
{
    public ICar CreateCar() => new Bmw();
}

// 调用示例
// ICarFactory factory = new BmwFactory();
// ICar car = factory.CreateCar();
// car.Drive(); // 输出:驾驶宝马汽车

4️⃣ 建造者模式(Builder)

设计意图:将复杂对象的构建过程拆分为多个步骤,分步构建,避免“构造函数参数爆炸”问题,同时支持不同组合的对象创建。 典型场景

  • 创建复杂实体(如订单对象:包含商品、收货地址、支付信息等)
  • 生成结构化文档(如 PDF:分步设置标题、正文、页码)
// 复杂产品:汽车(包含多个组件)
public class Car
{
    public string Engine { get; set; } // 发动机
    public string Wheel { get; set; }  // 轮胎
    public string Seat { get; set; }   // 座椅
}

// 建造者:封装构建步骤
public class CarBuilder
{
    private readonly Car _car = new Car(); // 待构建的产品

    // 分步构建:设置发动机
    public CarBuilder BuildEngine(string engineType)
    {
        _car.Engine = engineType;
        return this; // 链式调用
    }

    // 分步构建:设置轮胎
    public CarBuilder BuildWheel(string wheelBrand)
    {
        _car.Wheel = wheelBrand;
        return this;
    }

    // 最终构建:返回成品
    public Car Build() => _car;
}

// 调用示例
// Car car = new CarBuilder()
//     .BuildEngine("V8 发动机")
//     .BuildWheel("米其林轮胎")
//     .Build();
// Console.WriteLine($"发动机:{car.Engine},轮胎:{car.Wheel}");

5️⃣ 原型模式(Prototype)

设计意图:通过复制(克隆)已有对象(原型)创建新对象,避免重复执行复杂的初始化逻辑,提升创建效率。 典型场景

  • 游戏开发:复制游戏角色(基础属性相同,仅修改少量参数)
  • 大数据场景:复制基础查询条件对象(仅修改分页参数)
// 原型接口:实现 ICloneable
public class UserPrototype : ICloneable
{
    public string Name { get; set; }
    public int Age { get; set; }
    public List<string> Roles { get; set; } = new List<string>();

    // 浅克隆(值类型复制,引用类型复制引用)
    public object Clone()
    {
        // MemberwiseClone:CLR 内置浅克隆方法
        return this.MemberwiseClone();
    }

    // 深克隆(引用类型也复制新实例)
    public UserPrototype DeepClone()
    {
        var clone = (UserPrototype)this.MemberwiseClone();
        clone.Roles = new List<string>(this.Roles); // 重新创建集合
        return clone;
    }
}

// 调用示例
// UserPrototype prototype = new UserPrototype { Name = "张三", Age = 25 };
// prototype.Roles.Add("管理员");
// UserPrototype clone = (UserPrototype)prototype.Clone();
// Console.WriteLine(clone.Name); // 输出:张三

二、行为型设计模式(11 种)

核心目标:规范对象协作方式,明确职责边界 解决多个对象交互时的逻辑混乱、职责耦合问题,让协作更清晰、可扩展。


6️⃣ 策略模式(Strategy)

设计意图:将不同算法封装为独立的策略类,算法可自由替换,且算法变化不影响调用方。 典型场景

  • 电商折扣:普通用户/会员/VIP 不同折扣策略
  • 支付方式:微信支付/支付宝/银行卡不同支付逻辑
// 策略接口:定义算法规范
public interface IDiscountStrategy
{
    decimal Calculate(decimal originalPrice); // 计算折扣后价格
}

// 具体策略:VIP 8 折
public class VipDiscount : IDiscountStrategy
{
    public decimal Calculate(decimal originalPrice) => originalPrice * 0.8m;
}

// 具体策略:普通用户无折扣
public class NormalDiscount : IDiscountStrategy
{
    public decimal Calculate(decimal originalPrice) => originalPrice;
}

// 上下文:调用策略(屏蔽策略细节)
public class PriceContext
{
    private readonly IDiscountStrategy _strategy;

    // 注入策略
    public PriceContext(IDiscountStrategy strategy)
    {
        _strategy = strategy;
    }

    // 对外提供统一计算方法
    public decimal GetFinalPrice(decimal originalPrice)
    {
        return _strategy.Calculate(originalPrice);
    }
}

// 调用示例
// PriceContext context = new PriceContext(new VipDiscount());
// Console.WriteLine(context.GetFinalPrice(100)); // 输出:80

7️⃣ 模板方法模式(Template Method)

设计意图:在父类中定义算法的固定骨架,将可变的具体步骤延迟到子类实现,复用通用逻辑,扩展可变逻辑。 典型场景

  • 流程化操作:登录流程(通用步骤:验证→处理→返回;可变步骤:验证方式)
  • 框架开发:控制器基类(通用:请求接收→响应封装;可变:业务处理)
// 抽象父类:定义算法骨架
public abstract class AbstractOrderProcessor
{
    // 模板方法:固定算法流程(禁止子类重写)
    public void ProcessOrder()
    {
        ValidateOrder(); // 通用步骤1:验证订单
        CalculateAmount(); // 可变步骤:计算金额
        SaveOrder(); // 通用步骤2:保存订单
        NotifyUser(); // 可变步骤:通知用户
    }

    // 通用步骤:父类实现
    private void ValidateOrder() => Console.WriteLine("验证订单参数合法性");
    private void SaveOrder() => Console.WriteLine("保存订单到数据库");

    // 可变步骤:子类实现
    protected abstract void CalculateAmount();
    protected abstract void NotifyUser();
}

// 具体子类:实物订单处理器
public class PhysicalOrderProcessor : AbstractOrderProcessor
{
    protected override void CalculateAmount()
    {
        Console.WriteLine("计算实物订单金额(含运费)");
    }

    protected override void NotifyUser()
    {
        Console.WriteLine("发送物流短信通知");
    }
}

// 调用示例
// AbstractOrderProcessor processor = new PhysicalOrderProcessor();
// processor.ProcessOrder(); // 按固定流程执行

8️⃣ 观察者模式(Observer)

设计意图:定义“一对多”的依赖关系,当一个对象(主题)状态变化时,所有依赖它的对象(观察者)自动收到通知并更新。 典型场景

  • 事件通知:按钮点击后,多个组件响应(弹窗+日志+统计)
  • 消息订阅:订单支付成功后,库存服务、积分服务、通知服务同步更新
// 观察者接口:定义更新方法
public interface IObserver
{
    void Update(string message); // 接收主题通知
}

// 具体观察者:日志观察者
public class LogObserver : IObserver
{
    public void Update(string message) => Console.WriteLine($"日志记录:{message}");
}

// 具体观察者:通知观察者
public class NotifyObserver : IObserver
{
    public void Update(string message) => Console.WriteLine($"发送通知:{message}");
}

// 主题(被观察者):定义管理观察者和通知的接口
public class Subject
{
    private readonly 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(string message)
    {
        foreach (var observer in _observers)
        {
            observer.Update(message);
        }
    }
}

// 调用示例
// Subject subject = new Subject();
// subject.Attach(new LogObserver());
// subject.Attach(new NotifyObserver());
// subject.Notify("订单支付成功"); // 所有观察者收到通知

9️⃣ 责任链模式(Chain of Responsibility)

设计意图:将请求的处理者连成一条链,请求沿链传递,直到被某个处理者处理,避免请求发送者与接收者直接耦合。 典型场景

  • 权限校验:普通用户→VIP→管理员(不同级别处理不同权限请求)
  • 异常处理:基础异常→业务异常→系统异常(逐级处理)
// 抽象处理者:定义处理接口和下一个处理者
public abstract class Handler
{
    protected Handler _nextHandler; // 下一个处理者

    // 设置下一个处理者(链式组装)
    public Handler SetNext(Handler nextHandler)
    {
        _nextHandler = nextHandler;
        return nextHandler;
    }

    // 抽象处理方法
    public abstract void HandleRequest(int level);
}

// 具体处理者:初级处理者(处理级别1)
public class PrimaryHandler : Handler
{
    public override void HandleRequest(int level)
    {
        if (level == 1)
        {
            Console.WriteLine("初级处理者处理请求");
        }
        else if (_nextHandler != null)
        {
            _nextHandler.HandleRequest(level); // 传递给下一个
        }
    }
}

// 具体处理者:高级处理者(处理级别2)
public class AdvancedHandler : Handler
{
    public override void HandleRequest(int level)
    {
        if (level == 2)
        {
            Console.WriteLine("高级处理者处理请求");
        }
        else if (_nextHandler != null)
        {
            _nextHandler.HandleRequest(level);
        }
    }
}

// 调用示例
// Handler primary = new PrimaryHandler();
// Handler advanced = new AdvancedHandler();
// primary.SetNext(advanced); // 组装责任链
// primary.HandleRequest(2); // 高级处理者处理

🔟 命令模式(Command)

设计意图:将请求封装为独立的命令对象,使请求发送者与接收者解耦,支持请求的撤销、重试、队列化。 典型场景

  • 操作回滚:订单提交/撤销、支付/退款(命令可记录并反向执行)
  • 界面操作:按钮点击(点击事件封装为命令,可复用)
// 命令接口:定义执行/撤销操作
public interface ICommand
{
    void Execute(); // 执行命令
    void Undo();    // 撤销命令
}

// 接收者:实际执行操作的对象(如电灯)
public class Light
{
    public void TurnOn() => Console.WriteLine("电灯打开");
    public void TurnOff() => Console.WriteLine("电灯关闭");
}

// 具体命令:开灯命令
public class LightOnCommand : ICommand
{
    private readonly Light _light; // 关联接收者

    public LightOnCommand(Light light) => _light = light;

    public void Execute() => _light.TurnOn();
    public void Undo() => _light.TurnOff();
}

// 调用者:触发命令(如遥控器)
public class RemoteControl
{
    private ICommand _command;

    // 设置要执行的命令
    public void SetCommand(ICommand command) => _command = command;

    // 执行命令
    public void PressButton() => _command.Execute();

    // 撤销命令
    public void PressUndo() => _command.Undo();
}

// 调用示例
// Light light = new Light();
// ICommand onCommand = new LightOnCommand(light);
// RemoteControl remote = new RemoteControl();
// remote.SetCommand(onCommand);
// remote.PressButton(); // 开灯
// remote.PressUndo();   // 关灯

11️⃣ 状态模式(State)

设计意图:将对象的不同状态封装为独立的状态类,对象状态变化时自动切换行为,替代大量 if-else 判断。 典型场景

  • 订单状态:待支付→已支付→已发货→已完成(不同状态对应不同行为)
  • 电梯状态:空闲→运行→停止→故障(不同状态响应不同操作)
// 状态接口:定义状态对应的行为
public interface IOrderState
{
    void Handle(OrderContext context); // 处理当前状态的逻辑
}

// 具体状态:待支付
public class PendingPayState : IOrderState
{
    public void Handle(OrderContext context)
    {
        Console.WriteLine("订单待支付:可执行支付/取消操作");
        // 状态切换:支付后变为已支付
        context.State = new PaidState();
    }
}

// 具体状态:已支付
public class PaidState : IOrderState
{
    public void Handle(OrderContext context)
    {
        Console.WriteLine("订单已支付:可执行发货操作");
    }
}

// 上下文:维护当前状态,提供状态切换入口
public class OrderContext
{
    // 当前状态
    public IOrderState State { get; set; }

    public OrderContext(IOrderState initialState)
    {
        State = initialState;
    }

    // 执行当前状态的行为
    public void Process() => State.Handle(this);
}

// 调用示例
// OrderContext order = new OrderContext(new PendingPayState());
// order.Process(); // 执行待支付逻辑,切换为已支付状态
// order.Process(); // 执行已支付逻辑

12️⃣ 备忘录模式(Memento)

设计意图:保存对象的内部状态,在需要时恢复到指定状态,且不暴露对象的内部结构。 典型场景

  • 编辑器撤销:保存文档历史版本,支持撤销操作
  • 游戏存档:保存游戏角色状态,可回滚到之前的存档
// 备忘录:存储对象状态(不可修改)
public class Memento
{
    // 要保存的状态(如文档内容)
    public string Content { get; }

    public Memento(string content) => Content = content;
}

// 原发器:创建/恢复备忘录
public class Editor
{
    public string Content { get; set; } // 当前状态

    // 创建备忘录(保存当前状态)
    public Memento Save() => new Memento(Content);

    // 恢复备忘录(回滚状态)
    public void Restore(Memento memento) => Content = memento.Content;
}

// 管理者:管理备忘录(不修改,仅存储)
public class Caretaker
{
    private readonly List<Memento> _history = new List<Memento>();

    // 保存备忘录
    public void Add(Memento memento) => _history.Add(memento);

    // 获取指定版本的备忘录
    public Memento Get(int index) => _history[index];
}

// 调用示例
// Editor editor = new Editor { Content = "初始内容" };
// Caretaker caretaker = new Caretaker();
// caretaker.Add(editor.Save()); // 保存初始状态
// editor.Content = "修改后的内容";
// editor.Restore(caretaker.Get(0)); // 恢复到初始状态
// Console.WriteLine(editor.Content); // 输出:初始内容

13️⃣ 访问者模式(Visitor)

设计意图:将对象的操作与对象结构分离,新增操作时无需修改对象结构,仅新增访问者类。 典型场景

  • 数据导出:对不同类型的报表(订单/用户/商品)统一导出为Excel/PDF
  • 节点遍历:对树形结构的不同节点(文件夹/文件)执行不同操作(删除/复制)
// 元素接口:接受访问者
public interface IElement
{
    void Accept(IVisitor visitor);
}

// 具体元素:订单元素
public class OrderElement : IElement
{
    public decimal Amount { get; set; } = 1000;

    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this); // 接受访问者访问
    }
}

// 具体元素:用户元素
public class UserElement : IElement
{
    public string Name { get; set; } = "张三";

    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// 访问者接口:定义对不同元素的操作
public interface IVisitor
{
    void Visit(OrderElement order);
    void Visit(UserElement user);
}

// 具体访问者:导出Excel访问者
public class ExcelExportVisitor : IVisitor
{
    public void Visit(OrderElement order)
    {
        Console.WriteLine($"导出订单到Excel:金额{order.Amount}");
    }

    public void Visit(UserElement user)
    {
        Console.WriteLine($"导出用户到Excel:姓名{user.Name}");
    }
}

// 调用示例
// List<IElement> elements = new List<IElement>
// {
//     new OrderElement(),
//     new UserElement()
// };
// IVisitor visitor = new ExcelExportVisitor();
// foreach (var element in elements)
// {
//     element.Accept(visitor); // 统一执行导出操作
// }

14️⃣ 中介者模式(Mediator)

设计意图:引入中介者对象封装多个对象之间的交互,减少对象间的直接耦合,所有交互通过中介者完成。 典型场景

  • 聊天室:用户发送消息无需直接联系对方,通过聊天室(中介者)转发
  • 表单组件:输入框、按钮、提示框的交互由表单中介者统一管理
// 中介者接口:定义对象交互的方法
public interface IChatMediator
{
    void SendMessage(string message, User user); // 转发消息
    void AddUser(User user); // 添加用户
}

// 具体中介者:聊天室
public class ChatRoom : IChatMediator
{
    private readonly List<User> _users = new List<User>();

    public void AddUser(User user) => _users.Add(user);

    public void SendMessage(string message, User sender)
    {
        // 转发消息给所有非发送者
        foreach (var user in _users)
        {
            if (user != sender)
            {
                user.Receive(message);
            }
        }
    }
}

// 同事类:用户(所有交互通过中介者)
public class User
{
    private readonly IChatMediator _mediator;
    public string Name { get; }

    public User(IChatMediator mediator, string name)
    {
        _mediator = mediator;
        Name = name;
    }

    // 发送消息(通过中介者)
    public void Send(string message)
    {
        Console.WriteLine($"{Name} 发送消息:{message}");
        _mediator.SendMessage(message, this);
    }

    // 接收消息
    public void Receive(string message)
    {
        Console.WriteLine($"{Name} 接收消息:{message}");
    }
}

// 调用示例
// IChatMediator room = new ChatRoom();
// User user1 = new User(room, "张三");
// User user2 = new User(room, "李四");
// room.AddUser(user1);
// room.AddUser(user2);
// user1.Send("你好!"); // 李四接收消息

15️⃣ 解释器模式(Interpreter)

设计意图:定义语言的语法规则,并构建解释器来解释该语言的表达式,处理简单的语法解析。 典型场景

  • 简单公式计算:解析“1+2*3”等表达式
  • 规则引擎:解析自定义的业务规则(如“年龄>18 且 金额>1000”)
// 抽象表达式
public abstract class Expression
{
    public abstract int Interpret(); // 解释表达式
}

// 终结符表达式:数字
public class NumberExpression : Expression
{
    private readonly int _number;

    public NumberExpression(int number) => _number = number;

    public override int Interpret() => _number;
}

// 非终结符表达式:加法
public class AddExpression : Expression
{
    private readonly Expression _left;
    private readonly Expression _right;

    public AddExpression(Expression left, Expression right)
    {
        _left = left;
        _right = right;
    }

    public override int Interpret()
    {
        return _left.Interpret() + _right.Interpret();
    }
}

// 调用示例
// // 解析 1 + 2
// Expression expression = new AddExpression(new NumberExpression(1), new NumberExpression(2));
// Console.WriteLine(expression.Interpret()); // 输出:3

16️⃣ 迭代器模式(Iterator)

设计意图:提供统一的方式遍历集合对象,屏蔽不同集合(数组/列表/哈希表)的底层遍历实现。 典型场景

  • 自定义集合:为自定义容器(如树形集合)提供遍历接口
  • 统一遍历:对不同类型的集合执行相同的遍历逻辑
// 迭代器接口:定义遍历方法
public interface IIterator<T>
{
    bool HasNext(); // 是否有下一个元素
    T Next();       // 获取下一个元素
}

// 具体迭代器:列表迭代器
public class ListIterator<T> : IIterator<T>
{
    private readonly List<T> _list;
    private int _index = 0;

    public ListIterator(List<T> list) => _list = list;

    public bool HasNext() => _index < _list.Count;

    public T Next() => _list[_index++];
}

// 聚合接口:定义创建迭代器的方法
public interface IAggregate<T>
{
    IIterator<T> CreateIterator(); // 创建迭代器
}

// 具体聚合:自定义列表
public class CustomList<T> : IAggregate<T>
{
    private readonly List<T> _list = new List<T>();

    public void Add(T item) => _list.Add(item);

    public IIterator<T> CreateIterator()
    {
        return new ListIterator<T>(_list);
    }
}

// 调用示例
// CustomList<string> list = new CustomList<string>();
// list.Add("A");
// list.Add("B");
// IIterator<string> iterator = list.CreateIterator();
// while (iterator.HasNext())
// {
//     Console.WriteLine(iterator.Next()); // 输出:A、B
// }

三、结构型设计模式(7 种)

核心目标:优化类/对象的组合关系 通过灵活的结构设计,解决类/对象耦合过高、扩展困难、结构复杂的问题。


17️⃣ 适配器模式(Adapter)

设计意图:将一个类的接口转换为客户端期望的另一个接口,使原本接口不兼容的类可以协同工作。 典型场景

  • 第三方组件集成:老系统接口适配新框架接口
  • 数据格式转换:JSON 数据适配 XML 解析接口
// 目标接口:客户端期望的接口
public interface INewPaymentService
{
    void Pay(decimal amount); // 新支付接口
}

// 适配者:已有但接口不兼容的类
public class OldWeChatPay
{
    // 老接口(参数/方法名与新接口不一致)
    public void DoWeChatPay(double money)
    {
        Console.WriteLine($"微信支付:{money} 元");
    }
}

// 适配器:将老接口适配为新接口
public class WeChatPayAdapter : INewPaymentService
{
    private readonly OldWeChatPay _oldPay = new OldWeChatPay();

    // 适配老接口
    public void Pay(decimal amount)
    {
        // 类型转换 + 调用老方法
        _oldPay.DoWeChatPay(Convert.ToDouble(amount));
    }
}

// 调用示例
// INewPaymentService payService = new WeChatPayAdapter();
// payService.Pay(100); // 输出:微信支付:100 元

18️⃣ 装饰器模式(Decorator)

设计意图:动态地给对象添加额外功能,且不修改原对象的结构,功能可叠加。 典型场景

  • 功能增强:日志装饰器(给接口添加日志)、缓存装饰器(给查询添加缓存)
  • IO 流包装:Java IO 的 BufferedInputStream(装饰基础流)
// 组件接口:定义核心功能
public interface IDataService
{
    void GetData(); // 核心功能:获取数据
}

// 具体组件:基础实现
public class BasicDataService : IDataService
{
    public void GetData() => Console.WriteLine("获取基础数据");
}

// 装饰器抽象类:实现组件接口,关联被装饰对象
public abstract class DataServiceDecorator : IDataService
{
    protected readonly IDataService _service;

    public DataServiceDecorator(IDataService service) => _service = service;

    // 默认调用被装饰对象的方法
    public virtual void GetData() => _service.GetData();
}

// 具体装饰器:日志装饰(添加日志功能)
public class LogDecorator : DataServiceDecorator
{
    public LogDecorator(IDataService service) : base(service) { }

    public override void GetData()
    {
        Console.WriteLine("日志:开始获取数据"); // 新增功能
        base.GetData(); // 调用原功能
        Console.WriteLine("日志:获取数据完成"); // 新增功能
    }
}

// 调用示例
// IDataService service = new LogDecorator(new BasicDataService());
// service.GetData(); // 输出日志 + 基础数据获取

19️⃣ 代理模式(Proxy)

设计意图:为目标对象提供一个代理对象,控制对目标对象的访问(如权限校验、缓存、远程访问)。 典型场景

  • 权限控制:代理接口访问,校验用户权限
  • 远程代理:RPC 框架中,本地代理调用远程服务
  • 缓存代理:缓存查询结果,避免重复查询
// 主题接口:定义目标对象和代理的共同接口
public interface IProductService
{
    void GetProductInfo(int id); // 获取产品信息
}

// 真实主题:目标对象(实际执行业务)
public class ProductService : IProductService
{
    public void GetProductInfo(int id)
    {
        Console.WriteLine($"查询产品{id}的详细信息(数据库查询)");
    }
}

// 代理:控制对目标对象的访问(添加缓存逻辑)
public class ProductServiceProxy : IProductService
{
    private readonly IProductService _realService = new ProductService();
    private readonly Dictionary<int, string> _cache = new Dictionary<int, string>();

    public void GetProductInfo(int id)
    {
        // 缓存校验:有缓存则直接返回,无则调用真实对象
        if (_cache.ContainsKey(id))
        {
            Console.WriteLine($"缓存:{_cache[id]}");
        }
        else
        {
            _realService.GetProductInfo(id); // 调用真实对象
            _cache[id] = $"产品{id}缓存数据"; // 存入缓存
        }
    }
}

// 调用示例
// IProductService proxy = new ProductServiceProxy();
// proxy.GetProductInfo(1); // 数据库查询
// proxy.GetProductInfo(1); // 缓存返回

20️⃣ 外观模式(Facade)

设计意图:为复杂的子系统提供一个统一的简化接口,屏蔽子系统的复杂逻辑,降低客户端使用成本。 典型场景

  • 支付流程:整合“校验→扣款→通知→日志”等子系统,提供统一的 Pay 接口
  • 框架封装:ORM 框架封装数据库连接、SQL 执行、事务等逻辑
// 子系统1:库存服务
public class InventoryService
{
    public void ReduceStock(int productId)
    {
        Console.WriteLine($"扣减产品{productId}库存");
    }
}

// 子系统2:支付服务
public class PaymentService
{
    public void DeductMoney(decimal amount)
    {
        Console.WriteLine($"扣除金额{amount}元");
    }
}

// 子系统3:通知服务
public class NotifyService
{
    public void SendMessage()
    {
        Console.WriteLine("发送支付成功通知");
    }
}

// 外观类:封装子系统,提供统一接口
public class OrderFacade
{
    private readonly InventoryService _inventory = new InventoryService();
    private readonly PaymentService _payment = new PaymentService();
    private readonly NotifyService _notify = new NotifyService();

    // 统一的下单接口
    public void CreateOrder(int productId, decimal amount)
    {
        _inventory.ReduceStock(productId); // 调用子系统1
        _payment.DeductMoney(amount);      // 调用子系统2
        _notify.SendMessage();             // 调用子系统3
    }
}

// 调用示例
// OrderFacade facade = new OrderFacade();
// facade.CreateOrder(1, 100); // 一键下单,无需关心子系统细节

21️⃣ 桥接模式(Bridge)

设计意图:将“抽象部分”与“实现部分”分离,使两者可以独立变化,解决多维度变化导致的类爆炸问题。 典型场景

  • 图形绘制:形状(圆形/方形)与颜色(红色/蓝色)两个维度独立扩展
  • 支付系统:支付方式(微信/支付宝)与支付场景(APP/网页)独立扩展
// 实现部分接口:颜色(独立变化维度)
public interface IColor
{
    string GetColor(); // 获取颜色
}

// 具体实现:红色
public class RedColor : IColor
{
    public string GetColor() => "红色";
}

// 具体实现:蓝色
public class BlueColor : IColor
{
    public string GetColor() => "蓝色";
}

// 抽象部分:形状(独立变化维度)
public abstract class Shape
{
    protected IColor _color; // 桥接实现部分

    public Shape(IColor color) => _color = color;

    // 抽象方法:绘制
    public abstract void Draw();
}

// 具体抽象:圆形
public class Circle : Shape
{
    public Circle(IColor color) : base(color) { }

    public override void Draw()
    {
        Console.WriteLine($"绘制{_color.GetColor()}的圆形");
    }
}

// 调用示例
// Shape redCircle = new Circle(new RedColor());
// redCircle.Draw(); // 输出:绘制红色的圆形
// Shape blueCircle = new Circle(new BlueColor());
// blueCircle.Draw(); // 输出:绘制蓝色的圆形

22️⃣ 组合模式(Composite)

设计意图:将对象组合成树形结构,统一处理单个对象和组合对象(叶子节点/容器节点),无需区分处理。 典型场景

  • 文件系统:文件夹(容器)包含文件(叶子)和子文件夹,统一遍历/删除
  • 组织架构:公司→部门→员工,统一统计人数/计算薪资
// 组件接口:定义叶子和容器的共同方法
public interface IOrganization
{
    void Display(int depth); // 显示层级结构
    int GetCount(); // 统计数量
}

// 叶子节点:员工
public class Employee : IOrganization
{
    private readonly string _name;

    public Employee(string name) => _name = name;

    public void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + _name);
    }

    public int GetCount() => 1; // 单个员工,数量为1
}

// 容器节点:部门(包含员工/子部门)
public class Department : IOrganization
{
    private readonly string _name;
    private readonly List<IOrganization> _children = new List<IOrganization>();

    public Department(string name) => _name = name;

    // 添加子节点
    public void Add(IOrganization org) => _children.Add(org);

    public void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + _name);
        // 递归显示子节点
        foreach (var child in _children)
        {
            child.Display(depth + 2);
        }
    }

    public int GetCount()
    {
        // 统计所有子节点数量
        return _children.Sum(c => c.GetCount());
    }
}

// 调用示例
// // 构建组织架构:研发部→前端组→员工
// Department rdDept = new Department("研发部");
// Department feGroup = new Department("前端组");
// feGroup.Add(new Employee("张三"));
// feGroup.Add(new Employee("李四"));
// rdDept.Add(feGroup);
// rdDept.Display(1); // 显示层级结构
// Console.WriteLine($"总人数:{rdDept.GetCount()}"); // 输出:2

23️⃣ 享元模式(Flyweight)

设计意图:复用系统中频繁创建的相似对象,减少对象实例数量,降低内存消耗。 典型场景

  • 缓存池:线程池、数据库连接池(复用连接/线程)
  • 大量细粒度对象:游戏中的粒子、界面中的按钮样式
// 享元对象:包含共享状态(不可变)和非共享状态(可变)
public class Flyweight
{
    // 共享状态(如字体样式)
    public string Font { get; }

    public Flyweight(string font) => Font = font;

    // 执行操作(非共享状态作为参数传入)
    public void Display(string text)
    {
        Console.WriteLine($"字体:{Font},内容:{text}");
    }
}

// 享元工厂:管理享元对象,复用已有实例
public class FlyweightFactory
{
    // 缓存池:存储已创建的享元对象
    private readonly Dictionary<string, Flyweight> _pool = new Dictionary<string, Flyweight>();

    // 获取享元对象(有则复用,无则创建)
    public Flyweight GetFlyweight(string font)
    {
        if (!_pool.ContainsKey(font))
        {
            _pool[font] = new Flyweight(font);
            Console.WriteLine($"创建新享元:{font}");
        }
        return _pool[font];
    }

    // 获取缓存池大小
    public int GetPoolSize() => _pool.Count;
}

// 调用示例
// FlyweightFactory factory = new FlyweightFactory();
// Flyweight f1 = factory.GetFlyweight("宋体"); // 创建新享元
// f1.Display("Hello");
// Flyweight f2 = factory.GetFlyweight("宋体"); // 复用享元
// f2.Display("World");
// Console.WriteLine(factory.GetPoolSize()); // 输出:1

四、总结

核心要点回顾

  1. 三大分类核心定位:创建型解耦“对象创建”,行为型规范“对象协作”,结构型优化“对象组合”;
  2. 设计模式的本质:不是“炫技”,而是用成熟的结构解决特定问题,遵循 SOLID 原则,提升代码可维护性和扩展性;
  3. 使用原则:按需选择,不生搬硬套(如简单场景用简单工厂,无需强行用工厂方法)。

设计模式是软件开发的“通用解法”,掌握其核心思想(解耦、复用、扩展),比死记代码更重要。在面试中,重点说清“模式意图+使用场景+核心结构”,结合代码示例,就能形成完整的答题逻辑。

👋 关注我吧!

image