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

【设计模式】设计原则和常见的23种经典设计模式 阅读详情

在软件工程中,设计模式(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. 使用原则:按需选择,不生搬硬套(如简单场景用简单工厂,无需强行用工厂方法)。

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


👋 关注我吧!

SystemC实战:用C++搞芯片建模的5个典型场景(含代码示例) 本文通过五个典型实战场景,详细介绍了如何使用SystemC这一基于C++的硬件建模库进行芯片设计与系统级建模。内容涵盖从基础并发模块构建、事务级总线建模、跨时钟域验证,到与ModelSim协同仿真及多核系统性能探索,并提供了完整的代码示例,帮助软件工程师利用熟悉的C++工具链高效参与硬件架构设计与验证。 阅读详情

相关推荐

xHCI驱动学习(1) 核心数据结构

虽然Linux内核拥有C语言构建的身体,但它骨子里散发的是面向对象的气质,这一个个的对象就是struct。面对一个内核模块的时候,首先要找出关键的struct和它们之间的关系,才能摸清代码的骨骼脉络。今天来理清USB xHCI相关的数据结构类型usb_hcd、xhci_hcd、hc_driver和全局变量xhci_pci_driver、xhci_hc_driver、xhci_pci_hc_driver之间的关系。

1万+

设计模式之工厂模式

工厂模式 1、简单工厂模式 1.1、定义 简单工厂模式(Simple Factory Pattern)是指有一个工厂对象决定创建出哪一种产品类的实例,不属于23种设计模式。 简单工厂是产品的工厂 1.2、应用场景 简单工厂模式适用于工厂类创建的对象较少的场景,且客户端只需要传入工厂参数,对如何创建对象的逻辑不需要关心。 1.3、缺点 工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背了开闭原则。 不易于扩展过于复杂的产品结构。 1.4、实例 支付接口规范: public interface

aaa31203的博客 16万+

TruckSim与Simulink联合仿真中的车轮转角精确控制策略

本文深入探讨了TruckSim与Simulink联合仿真中实现车轮转角精确控制的关键策略。针对多轴车辆路径跟踪时转角指令失灵的常见问题,核心在于正确配置TruckSim转向轴的外部输入模式(Advanced Settings),并确保仿真接口的稳定搭建。文章详细解析了从单轴到多轴协同转向的配置方法,并提供了提升MPC路径跟踪精度的实战技巧与调试经验。

weixin_29035147的博客 367

Java设计模式:23种设计模式全面解析,墙都不扶就服你

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。 观察者模式:对象间的一对多的依赖关系。 仲裁者模式:用一个中介对象来封装一系列的对象交互。 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。 责任链模式:将请求的发送者..

m0_60747327的博客 1万+

ST-Link V2的隐藏技能:多通道串口调试的终极指南

本文深入探讨了ST-Link V2的多通道串口调试功能,突破传统烧录工具的限制。通过详细的硬件配置、Arduino IDE设置和实战案例,展示了如何利用SWD接口实现多通道数据监控,提升STM32F103C8T6等开发板的调试效率。文章还提供了PCB布局优化和性能调优技巧,助力开发者充分发挥ST-Link V2的潜能。

weixin_29285605的博客 355

Spine动画在Unity里卡顿、闪烁、排序错乱?这些性能优化与渲染问题一次讲清

本文深入解析了Spine动画在Unity中常见的卡顿、闪烁和排序错乱问题,提供了全面的性能优化与渲染解决方案。从性能瓶颈诊断到材质合并、动态合批优化,再到层级错乱与Alpha闪烁的处理,帮助开发者提升动画表现和运行效率。特别针对Unity和Spine的协同工作进行了详细的技术探讨。

weixin_29967445的博客 379

Java 中的 23 种设计模式详解

项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

微笑听雨 7万+

STM32 FATFS文件系统按行读取SD卡数据

STM32 SD数据实现按行读取

qq_32216815的博客 7824

23种设计模式

public static void send(User user, String msg) { /* 转发消息 */ }System.out.println(type + "子弹发射到(" + x + "," + y + ")");public void deliver() { System.out.println("陆运");System.out.println("书的价格:" + book.getPrice());System.out.println("微信支付:" + amount + "元");

qq_59463944的博客 9926

产品经理必看!用Cursor自动生成符合开发规范的技术文档(含UI设计规则模板)

本文详细介绍了产品经理如何利用Cursor工具自动生成符合开发规范的技术文档,并整合UI设计规则模板。通过配置标准化文档结构和设计关联规则,Cursor能有效解决术语不统一、结构混乱等问题,提升跨团队协作效率。文章包含实际案例、规则配置要点及企业级实施方案,帮助产品经理快速掌握AI辅助文档生成技巧。

emacs5lisp的博客 221

Open3D KD-tree的使用【2025最新版】

Open3d使用FLANN构建KDTree以便进行快速最近邻检索。博客长期更新,本文最近一次更新时间为:2025年1月1日,代码已同步更新至Open3D 0.18.0版本。

点云侠的博客 40万+

java常见的23种设计模式分类及核心范式解析

,复杂场景可结合Spring框架的IoC容器管理对象生命周期。避免过度设计,KISS原则(保持简单)永远有效。:优先使用Java标准库中的设计模式实现(如。:全局唯一的配置管理器、数据库连接池。:延迟加载、权限控制。

GanKuRenSheng的博客 212

tsfknn 预测R语言中的时间序列

rolling参数应该设置为FALSE,这使得最后的18个观测值成为测试集,其余的作为训练集;如果我们将rolling参数设置为默认值TRUE,那么测试集就不会是一个恒定的向量。lag 滞后参数表示时间序列数据的滞后值。在这个例子中,由于我们的时间序列数据是月度的,我们将参数设置为1:12。作为药品福利计划的一部分,澳大利亚健康保险委员会记录的属于ATC代码A10的产品的每月政府支出(百万美元)。我们将使用tsfknn包,它可以用来预测R语言中的时间序列。格式:ts类别的月度时间序列。

Mrrunsen的博客 322

史上最全--23种设计模式全解析

目录 一、设计模式的分类 二、设计模式的六大原则 总原则:开闭原则(Open Close Principle) 1、单一职责原则 2、里氏替换原则(Liskov Substitution Principle) 3、依赖倒转原则(Dependence Inversion Principle) 4、接口隔离原则(Interface Segregation Principle) 5...

不二的博客 8513

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Java开发中的23种设计模式详解

Java开发中的23种设计模式详解

gfuugff的博客 6万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

设计模式分类与功能

软件设计模式概述 文章目录软件设计模式概述1. 软件设计模式的产生背景2. 软件设计模式的概念与意义2.1. 软件设计模式的概念2.2. 学习设计模式的意义3. 软件设计模式的基本要素3.1. 模式名称3.2. 问题3.3. 解决方案3.4. 效果 本节使后面各章学习的基础,从整体上介绍软件设计模式的概念与特点、软件设计模式的基本要素,以及GoF的23中设计模式简介。 1. 软件设计模式的产生背景...

weixin_45452866的博客 518

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

java:23种设计模式全解析之一

java 23种设计模式全解析 本文地址:http://blog.csdn.net/shanglianlm/article/details/49660751一 设计模式的分类总体来说设计模式分为三大类: - 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 - 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 -

mingo_敏 2151

003-设计模式分类与结构

文章摘要: GoF设计模式分为创建型、结构型和行为型三大类。创建型模式(如单例、工厂)封装对象创建过程;结构型模式(如适配器、装饰器)处理类/对象组合;行为型模式(如观察者、策略)关注对象交互。每种模式包含标准要素:名称、问题描述、解决方案和效果评估。选择模式时需根据问题类型(创建、结构或行为)匹配适用模式,并考虑模式间的组合关系。设计模式通过标准化角色和结构,为常见设计问题提供可复用的解决方案。

wyl703的博客 1034

JAVA的23种设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化

Robin Hu的专栏 2818

设计模式学习之路 - 序言 - 记录自己的成长历程

做开发也有一段时间了, 从最开始的加班加点,为了不拖了其他人的进度甚至自己默默通宵认真学习的小鲜肉, 到现在的懒惰无力不思进取, 当一天和尚撞一天钟的小油条, 思绪万千, 觉得该整理一下思绪了, 互联网的世界, 逆流而上, 不进则退..还是要提起劲来. 所以,从最长用的设计模式开始入手了, 大家做开发的, 有事没事就谈设计模式, 面试过程中也是必问, 感觉设计模式有时候甚至成为了一个衡量

用优雅的代码铺通往成功的路 816

Java开发中的23种设计模式【转】

设计模式(Design Patterns)                                   ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编

lulin27860的专栏 1657

设计模式漫谈

1.设计模式 设计模式,是(Design Pattern)是解决问题的一系列套路。设计模式的出发点,不在程序运行的高效性,而在程序的工程性;因此,设计模式很重要的篇幅是如何解耦,从而让程序可以分隔而让程序更好维护。 设计模式真正成为一种“显学”,是由于GoF(Gang of Four,中文戏称为“四人帮”)在1995年写的《设计模式:可复用面向对象软件的基础》(Des...

wangzhezhilu001的专栏 385

设计模式概览

设计模式概览一、设计模式的分类二、设计模式的六大准则三、Java中的23种设计模式 一、设计模式的分类 总的来说设计模式分为3大类 创建型模式(5种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式 结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式 行为型模式(11种):状态模式、策略模式、访问者模式、迭代器模式、命令模式、观察者模式、中介...

MuskMelon 1288

java 23种设计模式详解

1. 软件设计模式意义 文章链接:http://c.biancheng.net/design_pattern/     设计模式的本质是对面向对象设计原则运用,是对类的封装、继承和多态以及类的关联关系和组合关系的充分理解。优点: 可以提高程序员的思维能力、编程能力和设计能力 使程序更加标准化、代码编写更加工程化,使软件开发效率大大提升,从而缩短开发周期 使...

那一抹回忆 1541

设计模式前传——学设计模式前你要知道这些

为什么要学设计模式? 面试经常被问到 以前总觉得设计模式是“花拳绣腿”,实际开发中没什么卵用,其实有好多种设计模式自己在无形中就使用了,只是自己不知道 设计模式是软件开发人员的“标准词汇”,学习设计模式是个人技术能力提高的捷径 设计模式包含了面向对象的精髓,“懂了设计模式,你就懂了面向对象分析和设计(OOA/D)的精要” 点赞+收藏 就学会系列,文章收录在 GitHub J...

新之助的学习之路 507

IOS 开发23种设计模式

转载:http://blog.sina.com.cn/s/blog_6bd977b90101916i.html设计模式主要分三个类型:创建型、结构型和行为型。 其中创建型有: 一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类

滴水可以穿石 百炼才能成钢,谋全局而通一域 致广大而尽精微 1148
上一篇: .NET 核心:Func 与 Action 委托(从入门到实战)
下一篇: WPF样式进阶实战:外置样式+MVVM主题切换+样式优先级全解析
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值