https://design-patterns.readthedocs.io/zh_CN/latest/index.html
https://www.tutorialspoint.com/design_pattern/design_pattern_overview.htm
https://springframework.guru/gang-of-four-design-patterns/
https://www.zhihu.com/question/20275578/answer/26577791
-
面向对象:Object 更准确的翻译应该叫物体,是对“世间万物”的抽象表示,属性即物体的状态,方法即物体的行为(状态转移),事件即描述物体进行状态转移的过程。
以下是面向对象编程语言提供的基本机制
-
封装:将一个物体的状态和行为都放到一个类中,并隐藏不必要的细节;
-
多态:将对其他物体的依赖描述为抽象接口,忽略不必要的细节;
-
继承:获取其他物体状态和行为,再根据需要修改细节,目的是为了复用已有代码而降低开发成本。
-
-
设计模式:设计方案来解决复杂的问题或实现复杂目标,将方案递归拆分成小的子方案,每个方案封装成一个函数或一个类来实现
- 复杂的部分抽离出去并封装起来;
- 通用的部分抽离出去并封装起来;
- 易变的部分抽离出去并封装起来;
- 抽离出的部分封装成什么?
- 需要状态 -> 类
- 无需状态 -> 函数
关系 | 符号 | 抽象概念 | 代码实现 |
---|---|---|---|
A 扩展 B | 空心三角箭头 + 实线 | A is-a B,B 存在具体实现 | A 继承 B |
A 实现 B | 空心三角箭头 + 虚线 | A is-a B,B 仅做抽象接口 | A 继承 B |
A 组合 B | 实心菱形箭头 + 实线 | A 作为整体不能没有部分 B,B 作为部分不能离开整体 A | B 作为 A 的值类型成员变量 |
A 聚合 B | 空心菱形箭头 + 实线 | A 作为整体可以没有部分 B,B 作为部分可独立存在且可共享 | B 作为 A 的引用类型成员变量 |
A 关联 B | 普通箭头 + 实线 | A 长久的使用 B | B 作为 A 的引用类型成员变量 |
A 依赖 B | 普通箭头 + 虚线 | A 临时的使用 B | B 作为 A 的方法的参数类型 |
创建型设计模式提供了一种在隐藏创建逻辑的同时创建对象的方法,而不是直接使用 new 操作符实例化对象。这使程序在决定需要为给定的用例创建哪些对象时更加灵活。
当一个抽象类体系中存在很多复杂的具体类时,利用工厂类,将创建对象时所需要的创建逻辑与具体类型集中隐藏起来管理,从而减少用户可能的硬编码。
利用抽象工厂(即工厂的工厂),它将多个工厂类组合起来,从而统一地创建一套内部相互关联的对象族。
将一个复杂类实例对象的创建过程分成两部分,Builder 负责可变或可选的部分(如原始数据),Director 负责不变的部分(如构建算法或数据校验)。
当构造函数开销很大时(如需要网络 IO 或磁盘 IO),不必对用户的每次请求都完全创建一个新对象,转而克隆原型对象获取其副本。
实现细节:
- 注意浅拷贝与深拷贝
- 考虑写时复制技术(Copy On Write)
仅允许类存在一个实例,并提供全局方法访问之,一般用于“管理类”和“工厂类”等
实现细节:
- 注意线程安全性,包括创建时与更改时
- 注意需求“延迟初始化”或“提前初始化”
结构型设计模式涉及类和对象组合。继承的概念用于组合接口和组合对象以获得新的功能。
使用享元工厂来创建对象,将可共享复用的内部数据与不可共享的外部状态分开创建,可提高整体性能。
当与多个子系统的交互比较复杂时,使用表观模式封装子系统从而避免用户与子系统耦合
注意:与中介者模式区别在于,表观为对外封装解耦,中介者为对内封装解耦
使用组合模式来创建层状树结构,并提供统一的方法来访问非叶节点和叶节点。
使用桥接模式来让类可以在两个维度上任意变换扩展和组合
使用代理对象来代替实际对象,从而控制实际对象的创建与访问。常见代理:
- 远程代理:延迟加载
- 虚拟代理:延迟创建
- COW 代理:写时复制
- 缓存代理:缓存结果
- 保护代理:权限区分
- 智能引用代理:引用计数
使用适配器来使将一个接口转换到互不兼容的另一个接口上工作。 优先选择组合,以下情况才考虑多重继承:
- 需要覆盖 virtual 函数实现
- 需要访问 protected 成员
- 需要空基类优化(EBO)
使用装饰器装饰(组合)基础对象来动态地为其附加额外的职责。各个职责相互独立从而可相互组合,若使用继承来扩展的话会产生很多类,代码过于冗余。
行为型设计模式特别关注对象之间的通信。
利用更改内部抽象对象来实现状态切换。
允许在运行时动态地选择一个算法族。
将算法的框架定义为一个抽象类,允许其子类提供具体的行为覆盖之。
访问者允许你定义一个新的操作,而不需要改变它所操作的元素的类。双分派技术缺点是当添加元素类时需要修改所有访问者。
利用组合模式实现语法解析器,若语言支持还可利用重载操作符。满足以下条件才适用:
- 业务规则频繁变化
- 类似的结构不断重复出现
- 并且容易抽象为语法规则的问题
按顺序访问对象的元素,而不暴露其底层表示。
在外部存储内部状态以届时恢复
赋予多个对象处理请求的机会,最终只有一个负责处理。
使用命令对象来传递请求,将请求的发送方与接收方解耦。类似制定通讯协议。
利用中介对象来隔离一系列对象的复杂交互,使同事类对象之间无需显示相互引用
是一种发布/订阅模式,允许多个观察者对象查看事件。