23种设计模式简述

设计模式学习笔记

github网址

1. 单例模式(创建型)

确保一个类仅有一个实例,并为其提供全局访问的入口。

  • 删除拷贝构造和赋值函数
  • 默认构造函数私有
  • 类内部自己保存唯一实例(static)
  • 暴露静态接口用于外部获取实例

适用场景:1. 日志系统(希望日志写在同个地方);2. 线程池(全局唯一)...

  • 优点
    1. 控制实例数量,避免重复创建,节省资源
    2. 方便全局访问
  • 缺点
    1. 全局变量对象化增加维护难度
    2. 代码耦合度变高
    3. 多线程下需谨慎处理

2. 原型模式(创建型)

复制已有对象按需修改后得到

  • 提供克隆接口,自行实现

适用场景:1. 对象创建代价高,创建逻辑复杂;2. 不清楚具体子类,但存在现成对象,可以直接克隆(比如CAD的clone接口)。

  • 优点

    1. 简化负责对象创建
    2. 提高性能(某些场景下复制比重新构造高效)
    3. 运行场景灵活,比如适用场景2
    4. 对具体创建细节进行封装屏蔽
  • ** 缺点**

    1. 有些对象与外界资源强绑定不适合复制(资源独占/上下文依赖)
    2. 深浅拷贝问题需要注意

3. 工厂方法模式(创建型)

父类定义工厂方法,子类进行对象创建

  • 将对象创建延迟到子类

适用场景:1. 无法提前确定要创建对象的具体类型;2. 创建逻辑与业务逻辑解耦;3.框架留扩展点

  • 优点

    1. 降低耦合
    2. 易于扩展
    3. 符合单一职责原则(业务类不负责创建)
  • 缺点

    1. 类数量增加,层次更多
    2. 如果对象固定且少,并且没有扩展需求,工厂方法模式可能设计过度

4. 抽象工厂模式(创建型)

提供接口用于创建"一组"产品(与工厂方法模式区分,工厂方法模式负责创建一个产品)

  • 生产多个相关对象
  • 保证产品之间一致性

适用场景:1. 跨平台UI库;2. 主题系统;

  • 优点

    1. 保证产品族间的一致性,且易于切换
  • 缺点

    1. 新增产品族容易,但新增产品族接口麻烦
    2. 类数量增多

5. 建造者模式(创建型)

把一个复杂对象的构建过程拆开,一步一步构造,这样同样的构建过程可以生成不同表示的对象。

  • 对象创建过程分步进行
  • 同样的创建步骤,可以组合出不同结果

适用场景:1. 电脑组装;2. 表格筛选查询对象;

  • 优点

    1. 减少构造函数参数,创建过程更清晰,可读性好
  • 缺点

    1. 代码量增加
    2. 对于简单对象而言有点重

6. 适配器模式(结构型)

适配器转换,使接口符合客户需求。

  • 不改变原有类代码,可复用已有功能
  • 让原本接口不兼容的类可以在一起工作

适用场景:1. 封装第三方SDK;2. 旧接口升级;3. 项目重构时兼容旧代码;

  • 优点

    1. 复用已有类,不用修改老代码,降低改动成本
    2. 将接口转换逻辑单独放在适配器中,逻辑更清晰
  • 缺点

    1. 代码结构复杂度升高
    2. 需注意预防适配器臃肿

7. 装饰器模式(结构型)

给对象套层外壳(做装饰)

  • 在不修改原类代码的情况下,动态地给对象增加功能
  • 比直接用继承扩展更灵活

适用场景:1. UI组件增加边框、滚动条;2. IO流包装;

  • 优点

    1. 复用已有类,不用修改老代码,降低改动成本
    2. 将接口转换逻辑单独放在适配器中,逻辑更清晰
  • 缺点

    1. 代码结构复杂度升高
    2. 需注意预防适配器臃肿

8. 代理模式(结构型)

给对象提供中介,外部不直接访问真是对象,而是先访问代理对象,由代理对象决定访问权限、访问时机。

适用场景:1. 权限控制代理;2. 缓存代理;3. 远程代理;

  • 优点

    1. 控制对象访问
    2. 支持延迟加载,提升性能
  • 缺点

    1. 代理让调用关系多了一层,可能会带来臃肿

9. 外观模式(结构型)

简化适用,将系统内部复杂子系统封装起来,对外提供一个统一的简化接口

适用场景:1. 编译系统构建;2. 图形系统统一绘制入口;

  • 优点

    1. 隐藏内部系统复杂性
    2. 降低调用方和子系统耦合
    3. 便于用户使用
  • 缺点

    1. 无法处理用户想调用子系统细节能力的情况

10. 桥接模式(结构型)

把抽象和实现拆开,让其独立变化,再通过组合将两边连接起来。

适用场景:1. 系统内有多个独立变化维度;2. 想用组合代替大量继承;

  • 优点

    1. 比纯继承更灵活
    2. 抽象和实现可以独立扩展
    3. 便于用户使用
  • 缺点

    1. 系统结构多出一层抽象,可读性不如简单模式

11. 组合模式(结构型)

把单个对象和由多个对象组成的整体,用统一方式来处理。

适用场景:1. 对象之间有明显的树形层级结构;2. 存在部分-整体关系;

  • 优点

    1. 统一单个对象和组合对象的使用方式
    2. 容易扩展新的节点类
  • 缺点

    1. 系统结构多出一层抽象,可读性不如简单模式

12. 享元模式(结构型)

将大量对象中可共享的部分提取出来复用,避免重复创建。

适用场景:1. 文字编辑器中的字符对象;2. 地图上的重复图块;

  • 优点

    1. 节省内存和对象创建的成本
    2. 共享状态集中管理,更高效
  • 缺点

    1. 注意区分内部状态和外部状态

13. 策略模式(行为型)

把多种可替换的行为封装成独立策略,在运行时按需要选择其中一种。

适用场景:1. 排序策略;2. 支付策略;

  • 优点

    1. 算法/行为可以独立扩展
    2. 符合开闭原则
    3. 调用方和具体实现解耦

14. 模板方法模式(行为型)

父类先定义好整体流程,子类只负责实现其中的某些具体步骤。

适用场景:1. 文档生成/导出流程(处理流程大体一致可复用);

  • 优点

    1. 复用公共流程代码
    2. 执行顺序可控
  • 缺点

    1. 不适合差异较大的场景
    2. 依赖继承,灵活性不高

15. 观察者模式(行为型)

当一个对象状态变化时,自动通知所有订阅它的对象。

适用场景:1. UI按钮点击事件;2. 消息订阅;

  • 优点

    1. 支持一对多通知,新增观察者方便
    2. 降低对象之间的耦合
  • 缺点

    1. 调试时不容易直接看出时谁触发了谁
    2. 容易导致效率问题
    3. 销毁对象和取消订阅时需要注意

16. 迭代器模式(行为型)

在不暴露容器内部实现的前提下,按统一接口顺序访问容器中的元素。

适用场景:1. offset globalbuffer节点遍历;2. 图元集合遍历;

  • 优点

    1. 隐藏容器内部实现
    2. 遍历逻辑可以独立出来

17. 责任链模式(行为型)

把多个处理对象连成一条链,让请求沿链传递,直到某个对象处理它为止。

适用场景:1. 请假审批流程;2. 异常处理链;

  • 优点

    1. 请求发送者与接收者解耦
    2. 避免大量条件判断
    3. 很适合流程化处理
  • 缺点

    1. 调试可能不够直观
    2. 链太长会影响理解和维护

18. 命令模式(行为型)

把一个操作请求封装成一个对象,从而让请求发送者和执行者解耦。

适用场景:1. 编辑器的撤消重做;2. 菜单命令;

  • 优点

    1. 请求调用者和执行者解耦
    2. 适合做操作记录、队列、宏命令
  • 缺点

    1. 如果将每个小操作都做成类,代码量会变很大

19. 备忘录模式(行为型)

在不暴露对象内部实现的情况下,保存对象过去的状态,并在需要时恢复。

适用场景:1. 游戏存档;2. 配置修改前保存旧状态;

  • 优点

    1. 方便恢复历史状态
    2. 将状态保存逻辑和对象本身业务逻辑分开
  • 缺点

    1. 需对历史记录进行管理,避免导致性能、内存占用劣化

20. 状态模式(行为型)

同一个对象,在不同状态下,对同一个请求的反应不一样。

适用场景:1. 订单状态;2. 电梯状态;3. 网络连接状态;

  • 优点

    1. 将不同状态下的行为拆分开,直观清晰
    2. 符合开闭原则
  • 缺点

    1. 状态之间切换导致理解成本升高

21. 访问者模式(行为型)

元素本身不负责做很多不同事情,而是让外部访问者来对它做事。

适用场景:1. 图形对象导出、打印、计算面积;2. 报表对象做多种统计分析;

  • 优点

    1. 便于操作新增、集中管理
    2. 减少元素类里堆太多无关方法
  • 缺点

    1. 新增元素类型较麻烦

22. 中介者模式(行为型)

大家不直接彼此联系,而是都通过"中间协调者"来配合。

适用场景:1. 聊天室系统;2. 智能家居中控;

  • 优点

    1. 降低对象之间的耦合
    2. 让各个对象的职责更单一
  • 缺点

    1. 系统的复杂度只是从对象之间转移到了中介者身上

22. 解释器模式(行为型)

给一套规则写"语法类",然后让程序自己去读懂并执行这些规则。

适用场景:1. 数学表达式解释;2. 正则或过滤表达式的小型实现;

  • 优点

    1. 扩展某些新规则比较自然
    2. 适合表示树形表达式结构
  • 缺点

    1. 语法一复杂,结构会迅速变得很绕
    2. 不适合大型复杂语言,且维护成本高
相关推荐
爱吃烤鸡翅的酸菜鱼3 小时前
【Java】封装位运算通用工具类——用一个整数字段替代几十个布尔列,极致节省存储空间
java·开发语言·设计模式·工具类·位运算·合成复用原则
geovindu4 小时前
go: Model,Interface,DAL ,Factory,BLL using mysql
开发语言·mysql·设计模式·golang·软件构建
guojb8245 小时前
当 Vue 3 遇上桥接模式:手把手教你优雅剥离虚拟滚动的业务大泥球
vue.js·设计模式
我登哥MVP5 小时前
【Spring6笔记】 - 15 - Spring中的八大设计模式
java·spring boot·笔记·spring·设计模式·intellij-idea
无籽西瓜a6 小时前
【西瓜带你学设计模式 | 第十六期 - 迭代器模式】迭代器模式 —— 统一遍历实现、优缺点与适用场景
java·后端·设计模式·迭代器模式·软件工程
程序员小寒6 小时前
JavaScript设计模式(十):模板方法模式实现与应用
前端·javascript·设计模式·模板方法模式
likerhood7 小时前
关于三种工厂的设计模式总结
设计模式
榴莲omega7 小时前
第14天:React 工程化与设计模式
前端·react.js·设计模式
dozenyaoyida1 天前
嵌入式设计模式之策略模式(1)
经验分享·设计模式·策略模式