23种设计模式(完整分类+核心解读)

23种设计模式是《设计模式:可复用面向对象软件的基础》(俗称“四人帮/Gof”)提出的经典分类,核心是解耦、复用、可扩展,按功能分为3大类:创建型(5种)、结构型(7种)、行为型(11种),适配几乎所有面向对象开发场景。

一、 创建型模式(5种)

核心:封装对象的创建过程,不直接new对象,让创建逻辑与业务逻辑分离,灵活控制对象实例化。
适合场景:对象创建复杂、需要统一管控、要隐藏创建细节时。

  1. 单例模式(Singleton)
    • 核心:保证一个类全局只有一个实例,并提供全局访问点。
    • 场景:全局配置、数据库连接池、日志对象。
    • 注意:线程安全(饿汉式/懒汉式/双重校验锁)、防止反射破坏。
  2. 工厂方法模式(Factory Method)
    • 核心:定义创建对象的接口,让子类决定具体创建哪个类,把创建延迟到子类。
    • 场景:日志框架(日志可以是文件/控制台/数据库,子类决定)、不同数据库驱动创建。
    • 优点:新增产品只需加子类,符合开闭原则。
  3. 抽象工厂模式(Abstract Factory)
    • 核心:提供一个接口,创建一系列相关/依赖对象,无需指定具体类(生产“产品族”)。
    • 场景:系统风格切换(Windows/Mac风格的按钮、输入框)、数据库配套组件(连接+事务+查询)。
    • 区别于工厂方法:工厂方法造“单一产品”,抽象工厂造“一组配套产品”。
  4. 建造者模式(Builder)
    • 核心:将复杂对象的构建与表示分离,相同构建过程能创建不同表示。
    • 场景:复杂对象创建(比如自定义电脑:CPU+内存+硬盘+显卡,组合不同配件)、HTTP请求构建。
    • 优点:分步构建、灵活控制细节,避免多参数构造器。
  5. 原型模式(Prototype)
    • 核心:通过复制已有实例(原型) 创建新对象,无需重新初始化,效率更高。
    • 场景:对象创建成本高(比如大数据对象、复杂初始化对象)、需要批量生成相似对象。
    • 关键:深克隆/浅克隆(浅克隆复制引用,深克隆复制对象本身)。

二、 结构型模式(7种)

核心:处理类或对象的组合关系,优化类结构、提高复用性,让结构更灵活且满足需求。
适合场景:需要组合已有类/对象实现新功能、解决类之间耦合、优化复杂结构时。

  1. 适配器模式(Adapter)
    • 核心:将一个类的接口转换成客户端期望的另一个接口,让不兼容的类能一起工作(“转换器”)。
    • 场景:新旧系统兼容(比如老接口返回List,新系统需要Set)、第三方组件适配。
    • 分类:类适配器(继承)、对象适配器(组合,更推荐)。
  2. 桥接模式(Bridge)
    • 核心:将抽象部分与实现部分分离,让两者可以独立变化,解耦抽象和实现。
    • 场景:多维度变化的场景(比如“形状”和“颜色”:形状有圆形/方形,颜色有红/蓝,两者独立扩展)、消息通知(通知方式:短信/邮件;通知类型:普通/紧急)。
    • 优点:避免类爆炸(不用创建圆形红、圆形蓝、方形红...等大量子类)。
  3. 组合模式(Composite)
    • 核心:将对象组合成树形结构,表示“部分-整体”关系,让客户端统一处理单个对象和组合对象。
    • 场景:树形结构场景(文件夹+文件、菜单+子菜单+菜单项、部门组织架构)。
    • 关键:叶子节点(无子节点,如文件)和组合节点(有子节点,如文件夹)实现统一接口。
  4. 装饰器模式(Decorator)
    • 核心:动态给对象添加额外功能,不改变原类结构,比继承更灵活(“锦上添花”)。
    • 场景:功能动态扩展(比如咖啡:基础咖啡+加奶+加糖+加冰,自由组合)、IO流包装(Java中BufferedReader装饰InputStream)。
    • 区别于继承:继承是静态扩展,装饰器是动态扩展,可叠加。
  5. 外观模式(Facade)
    • 核心:为复杂子系统提供统一的对外接口,简化客户端调用,隐藏子系统细节。
    • 场景:复杂系统调用(比如电商下单:需要调用库存、支付、物流子系统,外观类封装成一个“下单”方法)、框架对外API。
    • 优点:降低客户端与子系统的耦合,简化使用。
  6. 享元模式(Flyweight)
    • 核心:复用内存中已存在的对象,减少创建大量相似对象的内存消耗,共享“细粒度对象”。
    • 场景:大量重复对象场景(比如围棋棋子、验证码字体、池化技术)。
    • 关键:区分内部状态(共享,如棋子颜色)和外部状态(不共享,如棋子位置)。
  7. 代理模式(Proxy)
    • 核心:为其他对象提供一个代理对象,控制对原对象的访问,可附加额外逻辑。
    • 场景:权限控制、日志记录、懒加载、远程调用(RPC)。
    • 分类:静态代理(编译期确定)、动态代理(运行时生成,如Java的JDK代理、CGLIB)。

三、 行为型模式(11种)

核心:处理类或对象之间的交互与职责分配,规范通信方式,让交互更清晰、职责更明确,提高灵活性。
适合场景:需要定义对象间通信规则、分配职责、处理算法变化时。

  1. 责任链模式(Chain of Responsibility)
    • 核心:将请求的发送者和接收者解耦,多个接收者连成链,请求沿链传递,直到被处理。
    • 场景:多级审批(请假:组长→部门经理→总监)、过滤器链(Web请求过滤)、异常处理链。
    • 优点:新增处理器只需加节点,无需修改原有链。
  2. 命令模式(Command)
    • 核心:将请求封装成独立的命令对象,包含接收者和执行逻辑,支持请求的排队、撤销、重做。
    • 场景:按钮点击事件(点击按钮=执行对应命令)、任务队列、撤销操作(比如编辑器撤回)。
    • 角色:命令(接口)、具体命令、调用者(触发命令)、接收者(执行实际逻辑)。
  3. 解释器模式(Interpreter)
    • 核心:定义语言的文法规则,并构建解释器来解释语言中的句子。
    • 场景:简单语法解析(比如表达式计算1+2*3、正则表达式解析、配置文件解析)、自定义小型DSL。
    • 缺点:文法复杂时类会爆炸,只适合简单场景。
  4. 迭代器模式(Iterator)
    • 核心:提供一种方法顺序访问集合对象的元素,无需暴露集合的内部结构。
    • 场景:遍历集合(比如Java的Iterator、Python的for循环迭代)、统一不同集合的遍历方式。
    • 优点:遍历和集合解耦,新增集合只需实现迭代器接口。
  5. 中介者模式(Mediator)
    • 核心:定义一个中介对象,封装多个对象之间的交互,让对象无需直接通信,降低耦合。
    • 场景:多对象复杂交互(比如聊天室(中介):用户不用直接发消息给对方,发给聊天室转发)、GUI组件交互。
    • 优点:减少对象间的直接依赖,交互逻辑集中管理。
  6. 备忘录模式(Memento)
    • 核心:在不破坏封装的前提下,保存对象的内部状态,以便后续恢复(“快照”)。
    • 场景:数据备份与恢复(比如编辑器保存草稿、游戏存档、撤销操作)。
    • 角色:原发器(保存状态)、备忘录(存储状态)、管理者(管理备忘录,不修改)。
  7. 观察者模式(Observer)
    • 核心:定义一对多的依赖关系,当一个对象(被观察者)状态变化,所有依赖它的对象(观察者)自动收到通知并更新。
    • 场景:发布-订阅模型(比如公众号推送、消息通知、事件监听)、数据绑定。
    • 分类:推模型(被观察者主动推数据)、拉模型(观察者主动拉数据)。
  8. 状态模式(State)
    • 核心:将对象的状态封装成独立的状态类,对象状态变化时,切换对应的状态类,让行为随状态改变而改变。
    • 场景:对象有多种状态且行为随状态变化(比如订单状态:待付款→待发货→待收货→完成)、电梯运行状态。
    • 区别于条件判断:用状态类替代if-else/switch,更清晰、易扩展。
  9. 策略模式(Strategy)
    • 核心:定义一系列算法,将每个算法封装成独立类,让它们可以互相替换,算法变化不影响使用算法的客户端。
    • 场景:算法灵活切换(比如排序算法:冒泡/快排/归并、支付方式:微信/支付宝/银行卡)。
    • 优点:避免多重条件判断,算法可复用、易扩展。
  10. 模板方法模式(Template Method)
    • 核心:在父类中定义算法的骨架(模板),将可变的步骤延迟到子类实现,固定流程、灵活细节。
    • 场景:流程固定但细节不同(比如泡茶/泡咖啡:流程都是“烧水→放原料→冲泡→倒出”,原料不同)、框架核心流程(比如Spring的Bean生命周期)。
    • 关键:父类控制流程,子类实现细节,符合“开闭原则”。
  11. 访问者模式(Visitor)
    • 核心:将数据结构和数据操作分离,新增操作时无需修改数据结构,只需加访问者类。
    • 场景:数据结构稳定、操作频繁变化(比如报表生成:同一批数据,生成Excel/Word/PDF报表,数据不变,操作变化)。
    • 缺点:数据结构变化时,所有访问者都要修改,适合结构稳定的场景。

四、 关键补充(开发必知)

1. 设计模式的核心原则(底层支撑)

所有设计模式都围绕SOLID原则展开,是判断是否用对模式的标准:

  • 单一职责:一个类只做一件事
  • 开闭原则:对扩展开放,对修改关闭(核心)
  • 里氏替换:子类可替换父类且不影响功能
  • 接口隔离:接口要细化,不依赖不需要的方法
  • 依赖倒置:依赖抽象,不依赖具体实现

2. 常用模式优先级(开发高频)

不用死记所有模式,优先掌握这些高频款即可覆盖80%场景:

  • 必学:单例、工厂方法、装饰器、代理、观察者、策略、模板方法
  • 常用:建造者、适配器、外观、责任链、状态
  • 小众:抽象工厂、桥接、组合、享元、原型、解释器、中介者、备忘录、访问者

3. 避坑提醒

  • 不要过度使用:简单场景用简单代码,不用强行套模式(比如单例不要滥用,非全局唯一没必要)
  • 优先组合,少用继承:设计模式大多推荐“组合/聚合”,比继承更灵活
  • 模式是工具,不是规范:核心是解决问题,不是为了用模式而用模式