You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

587 lines
19 KiB
Markdown

## 设计模式
### 7大设计原则
开闭原则
依赖倒置原则
单一职责原则
接口隔离原则
迪米特原则
里氏替换原则
合成复用原则
### 设计模式 - 创建型模式
工厂模式,抽象工厂模式,建造者模式,单例模式,原型模式
### 设计模式 - 结构型模式
适配器模式,装饰者模式,代理模式,外观模式,桥接模式,组合模式,享元模式
### 设计模式 - 行为型模式
策略模式,观察者模式,责任链模式,备忘录模式,模板方法模式,迭代器模式,中介者模式,命令模式,访问者模式,解释器模式,状态模式
### UML类图
- 记忆技巧
- 箭头方向 子类指向父类
- 实线继承 | 虚线实现(空心箭头)
- 实线关联 | 虚线依赖
- 空心菱形-聚合 | 实心菱形-组合
### UML时序图
- 记忆技巧
- 实心箭头-同步调用
- 线箭头-异步调用
- 虚线箭头-返回
### UML类图讲解
### 软件设计七大原则
---
### 简单工厂
#### 1 定义与类型
定义:由一个工厂对象决定创建出哪一种产品类的实例
类型:创建型,但不属于GOF23种设计模式
#### 2 适用场景
工厂类负责创建的对象比较少
客户端(应用层)只知道传入工厂类的参数对于如何创建对象(逻辑)不关心
#### 3 优点
只需要传入一个正确的参数,就可以获取你所需要的对象而无需知道其创建细节
#### 4 缺点
工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违背开闭原则
#### 5 coding
com.baiye.design.pattern.creational.simplefactory
---
### 工厂方法
#### 1 定义与类型
定义与类型: 定义一个创建对象的接口但让实现这个接口的类决定实例化哪个类工厂方法让类的实例化推迟到子类中进行
类型: 创建型
#### 2 适用类型
常见对象需要大量重复的代码
客户端(应用层)不依赖于产品类实例如何被创建,实现等细节
一个类通过其子类来指定创建哪个对象
#### 3 优点
用户只需要关心所需产品对应的工厂,无需关心创建细节
加入新产品符合开闭原则,提高可扩展性
#### 4 缺点
类的个数容易过多,增加复杂度
增加了系统的抽象性和理解难度
#### 5 coding
com.baiye.design.pattern.creational.factorymethod
#### 6 总结
产品有明确的产品组的同类特征的时候
---
### 抽象工厂
#### 1 定义与类型
定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口
无需指定它们具体的类
类型:创建型
#### 2 适用场景
客户端(应用层)不依赖于产品类实例如何被创建,实现等细节
强调一系列相关的产品细节(属于同一产品族)一起使用创建对象需要大量重复的代码
提供了一个产品类的类,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
#### 3 优点
具体产品在应用层代码隔离,无需关心创建细节
将一个系列的产品族统一到一起创建
#### 4 缺点
规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂接口
增加了系统的抽象性和理解难度
#### 5 抽象工厂 - 产品等级结构与产品族
产品族:统一品牌的冰箱,洗衣机,空调等
产品等级结构:比如所有的空调啥的
#### 6 coding
com.baiye.design.pattern.creational.abstractfactory
---
### 建造者模式
#### 1 定义与类型
定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
用户只需指定需要建造的类型就可以得到它们,建造过程及细节不需要知道
类型:创建型
#### 2 使用场景
如果一个对象有非常复杂的内部结构(很多属性)
想把复杂对象的创建和使用分离
#### 3 优点
封装性好,创建和使用分离
扩展性好,建造类之间独立,一定程度上解耦
#### 4 缺点
产生多余的Builder对象
产品内部发生变化,建造者都要修改,成本较大
#### 5 Coding
com.baiye.design.pattern.creational.builder
#### 6 总结
适合做配置类的编写和实体类
---
### 单例模式
#### 1 定义与类型
定义:保证一个类仅有一个实例,并提供一个全局访问点
类型:创建型
#### 2 适用场景
想确保任何情况下都绝对只有一个实例
#### 3 优点
在内存里只有一个实例,减少了内存开销
可以避免对资源的多重占用
设置了全局访问点,严格控制访问
#### 4 缺点
没有接口,扩展困难
#### 5 重点
私有构造器
线程安全
延迟加载
序列化和反序列化安全
反射
#### 6 单例模式相关的设计模式
单例模式和工厂模式
- 可以把工厂类设计为单例的
单例模式和享元模式
- 享元模式是单例对象的一个工厂
#### 7 Coding
---
### 原型模式
#### 1
---
### 外观模式
#### 1 定义与类型
定义: 又叫门面模式,提供了一个统一的接口,用来访问子系统中的一群接口
外观模式定义了一个高层接口,让子系统更容易使用
类型: 结构型
#### 2 使用场景
子系统越来越复杂,增加外观模式提供简单调用接口
构建多层系统结构,利用外观对象作为每层入口,简化层间调用
#### 3 优点
简化了调用过程,无需了解深入子系统,防止带来风险
减少系统依赖,松散耦合
更好的划分访问层次
符合迪米特法则,即最少知道原则
#### 4 缺点
增加子系统,扩展子系统行为行为很容易引入风险
不符合开闭原则
#### 5 相关的设计模式
外观模式和中介者模式
- 外观模式关注是外部和子系统的交互
- 中介者模式关注是子系统内部的交互
外观模式和单例模式
- 外观模式中的独外观对象做成单例对象使用
外观模式和抽象工厂模式
- 外观类可以通过抽象工厂获取子系统的实例
#### 6 coding
com.baiye.design.pattern.structural.facade
---
### 装饰者模式
#### 1 定义与类型
定义: 在不改变原有对象的基础上,架构功能附加到对象上
提供了比继承更有弹性的替代方案(扩展原有对象功能)
类型:结构型
#### 2 适用场景
扩展一个类的功能或者给一个类添加附加职责
动态的给一个对象添加功能,这些功能可以再动态的撤销
#### 3 优点
继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
通过使用不同装饰类及这些装饰类的排列组合,可以实现不同效果
符合开闭原则
#### 4 缺点
会出现更多的代码,更多的类,增加程序的复杂性
动态装饰时,多层装饰时会更复杂
#### 5 相关的设计模式
装饰者模式和代理模式
- 装饰者模式: 关注在一个对象上动态的添加方法
- 代理模式: 关注控制对对象的访问
装饰者模式和适配器模式
- 装饰者模式:装饰者和被装饰者实现相同的接口或装饰者是被装饰者的子类,(也可以退化成半装饰者,装饰者还提供了其他的方法,但是不常用)
- 适配器模式: 适配器和被适配的类有不同的接口,也可能有部分的接口是重合的
#### 6 代码
com.baiye.design.structural.decorator
#### 7 总结
以 Wapper 结尾的可能是装饰者或者适配器模式,具体看结构
---
### 适配器模式
#### 1 定义和类型
定义: 将一个类的接口转换成客户期望的另一个接口
使原本接口不兼容的类可以一起工作
类型:结构型
#### 2 适用场景
已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同情况下的解决方案
#### 3 优点
能提高类的透明性和复用性,现有的类复用但不需要改变
目标类和适配器类解耦,提高程序的扩展性
符合开闭原则
#### 4 缺点
适配器模式编写过程需要全面考虑,可能会增加系统的复杂性
增加系统代码可读的难度
#### 5 扩展
对象适配器
类适配器
#### 6 相关的设计模式
适配器和外观模式
- 外观是定义新的接口,适配器是复用一个原有的接口,适配器是让两个接口协同工作,外观是在现有的系统中提供一个访问入口
#### 7 代码
com.baiye.design.structural.adapter
---
### 享元模式
#### 1 定义和类型
定义:提供了减少对象数量从而改善应用所需对象结构的方式
运用共享技术有效地支持大量细粒度的对象
类型: 结构型
#### 2 使用场景
常常应用于系统底层的开发,以便解决系统的性能问题
系统有大量相似对象,需要缓冲池的场景
#### 3 优点
减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率
减少内存之外的其他资源占用
#### 4 缺点
关注 内部/外部状态,关注线程安全问题
使系统,程序的逻辑复杂化
#### 5 扩展
内部状态
外部状态
#### 6 相关的设计模式
享元模式和代理模式
享元模式和单例模式
---
### 组合模式
#### 1 定义和类型
定义:将对象组合成树形结构以表示“部分-整体”的层次结构
组合模式使客户端对单个对象和组合对象保持一致的方式处理
类型:结构型
#### 2 适用场景
希望客户端可以忽略组合对象与单个对象的差异时
处理一个树形结构时
#### 3 优点
清除地定义分层次的复杂对象,表示对象的全部或部分层次
让客户端忽略了层次的差异,方便对整个层次结构进行控制
简化客户端代码
符合开闭原则
#### 4 缺点
限制类型时会较为复杂
使设计变得更加抽象
#### 5 组合模式的相关设计模式
组合模式和访问者模式
- 使用访问者模式可以访问组合模式中的递归结构
#### 6 代码
com.baiye.design.structural.composite
---
### 桥接模式
#### 1 定义与类型
定义: 将抽象的部分与它的具体实现部分分离,使它们都可以独立地变化
通过组合的方式建立两个类之间联系,而不是继承
类型:结构型
#### 2 使用场景
抽象和具体实现之间增加更多的灵活性
一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展
不希望使用继承,或因为多层继承导致系统类的个数剧增
####3 优点
分离抽象部分及其具体实现部分
提高了系统的可扩展性
符合开闭原则
符合合成复用原则
#### 4 缺点
增加了系统的理解与设计难度
需要正确的识别出系统中两个独立变化的维度
#### 5 桥接-相关设计模式
桥接模式和组合模式
- 组合模式是强调部分和整体之间的组合
- 桥接模式是平行级别上的组合
桥接模式和适配器模式
- 都是为了让两个东西配合工作
- 适配器模式是改变已有的接口,让他们之间可以相互配合
- 桥接模式是分离抽象和他们具体的实现,目的是分离
#### 6 coding
# todo
---
### 模板方法模式
#### 1 定义与类型
定义: 定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现
模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤
类型:行为型
#### 2 使用场景
一次性实现一个算法不变的部分,并将可变的行为留给子类来实现
各子类中公共的行为被提取出来并集中到一个公共父类中,从而避免代码重复
#### 3 优点
提高复用性 相同的放在父类中
提高扩展性 不同的放在子类中
符合开闭原则
#### 4 缺点
类数目增加
增加了系统实现的复杂度
继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍
#### 5 模板方法-扩展
钩子方法 - 提供了缺省行为 - 子类在必要时候进行扩展
#### 6 模板方法 - 相关设计模式
模板方法和工厂方法模式
- 工厂方法是模板方法的一种特殊实现
模板方法和策略模式
- 策略模式是使不同的方法可以相互替换,并且不影响应用层客户端的使用
- 模板方法模式是定义流程,把不太一样的具体实现交给子类
#### 7 coding
com.baiye.design.behavioral.templatemethod
#### 8 总结
解决 if-else 问题
---
### 迭代器模式
#### 1 定义与类型
定义:提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示
类型:行为型
#### 2 使用场景
访问一个集合对象的内容而无需暴露它的内部表示
为遍历不同集合结构提供一个统一的接口
#### 3 优点
分离了集合对象的遍历行为
#### 4 缺点
类的个数成对增加
#### 5 迭代器 - 相关设计模式
迭代器和访问者模式
- 都是迭代的访问一个集合内的元素
- 访问者模式中扩展开放的部分,再作用于对象的操作上
- 迭代器模式,扩展开放的部分,作用在迭代器的种类上
#### 6 coding
com.baiye.design.behavioral.iterator
---
### 策略模式
#### 1 定义与类型
定义: 定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法用户
if .. else ..
类型: 行为型
#### 2 适用场景
系统有很多类,而他们的区别仅仅是在于他们的行为不同
一个系统需要动态的在几种算法中选择一种
#### 3 优点
开闭原则
避免使用多重条件转移语句
提高算法的保密性和安全性
#### 4 缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类
产生很多策略类
#### 7 策略模式相关的设计模式
策略模式和工厂模式
- 工厂模式是去创建对象,策略模式是接收已经创建好的对象
策略模式和状态模式
- 策略模式客户端需要知道选择是哪个策略
- 状态模式客户端是不需要关心具体的状态的,状态会自动转换
#### 8 coding
---
### 解释器模式
#### 1 定义与类型
定义: 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
为解释一种语言,而为语言创建的解释器
类型:行为型
#### 2 适用场景
某个特定类型问题发生频率足够高
#### 3 优点
语法由很多类表示,容易改变及扩展此"语言"
#### 4 缺点
当语法规则数目太多时,增加了系统复杂度
#### 5 解释器模式-相关设计模式
解释器模式和适配器模式
- 适配器模式是不需要提前知道适配的规则
- 解释器需要我们把规则写好,用规则进行解释
#### 6 coding
com.baiye.design.behavioral.interpreter
#### 7 总结
使用比较少
xxxxExpressionParser 命名规范
---
### 观察者模式
#### 1 定义与类型
定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题的对象,当主题对象发生变化时,它的所有依赖者(观察者)都会收到通知并更新
类型: 行为型
#### 2 使用场景
关联行为场景,建立一套触发机制
#### 3 优点
观察者和被观察者之间建立了一个抽象的耦合
观察者模式支持广播通信
#### 4 缺点
观察者之间有过多的细节依赖,提高时间消耗及程序复杂度
使用要得当,避免循环调用
#### 5 coding
com.baiye.design.behavioral.observer
#### 6 总结
Guava 的 EventBus 可以很方便的进行实现观察者模式
---
### 备忘录模式
#### 1 定义与类型
定义: 保存一个对象的某个状态,以便在适当的时候恢复对象
"后悔药"
类型: 行为型
#### 2 使用场景
保存及恢复数据相关业务场景
后悔的时候,即想恢复到之前的状态
#### 3 优点
为用户提供一种可恢复机制
存档信息的封装
#### 4 缺点
资源占用
#### 5 备忘录模式 - 相关的设计模式
备忘录模式和状态模式
- 备忘录模式是用实例来表示状态的
- 状态是用类来表示状态的
#### 6 coding
com.baiye.design.behavioral.memento
#### 7 总结
工作流中
---
### 中介者模式
#### 1 定义与类型
定义 一个封装一组对象 如何交互的对象
通过使对象明确地相互作用来促进松散耦合,并允许独立地改变他们的交互
类型: 行为型
#### 2 使用场景
系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
交互的公共行为,如果需要改变行为则可以增加新的中介者类
#### 3 优点
将一对多转化成1对1降低程序复杂性
类之间的解耦
#### 4 缺点
中介者过多,导致系统复杂
#### 5 中介者模式 - 相关设计模式
中介者模式和观察者模式
- 使用观察者模式来实现中介者模式中的角色相互的通信
#### 6 coding
com.baiye.design.behavioral.mediator
#### 7 总结
群,啥的批量操作都是中介者
---
### 责任链模式
#### 1 定义与类型
为请求创建一个接收此次请求对象的链
类型: 行为型
#### 2 使用场景
一个请求的处理需要多个对象当中的一个或多个协作处理
#### 3 优点
请求的发送者和接收者(请求的处理)解耦
责任链可以动态组合
#### 4 缺点
责任链太长或者处理时间过长,影响性能
责任链有可能过多
#### 5 相关的设计模式
责任链模式和状态模式
- 责任链模式不指定下一个处理的对象
- 状态模式是知道自己处理的下一个对象是谁
#### 6 代码
com.baiye.design.behavioral.chainofresponsibility
#### 7 总结
责任链 -> 流程引擎
一般责任链模式的都以Chain结尾
---
### 访问者模式
#### 1 定义与类型
封装作用于某数据结构(如List/Set/Map等)中的各元素的操作
可以在不改变各元素类的前提下,定义作用于这些元素的操作
类型:行为型
#### 2 适用场景
当一个数据结构(List/Set/Map等)包含很多类型对象
数据结构与数据操作分离
#### 3 优点
增加新的操作很容易,即增加一个新的访问者
#### 4 缺点
增加新的数据结构困难
具体元素的变更比较麻烦
#### 5 相关设计模式
访问者模式和迭代器模式
- 都是在某种数据结构上进行处理
- 访问者模式在对保存在数据结构中的元素进行某种特定处理
- 迭代器模式是逐步遍历保存在数据结构中的元素
#### 6 coding
com.baiye.design.behavioral.visitor
#### 7 总结
不同角色的人对数据的访问不同
一般以Visitor结尾的各种类
---
### 状态模式
#### 1 定义与类型
允许一个对象在其内部状态改变时,改变他的行为
类型: 行为型
#### 2 使用场景
一个对象存在多个状态(不同状态下行为不同),且状态可相互转换
#### 3 优点
将不同的状态隔离
把各种状态的转换逻辑,分布到State的子类中,减少相互间依赖
增加新的状态非常简单
#### 4 缺点
状态多的业务场景导致类的数目增加,系统变复杂
#### 5 相关的设计模式
状态模式和享元模式
- 使用享元模式在多个状态上下文中共享这个模式
#### 6 coding
com.baiye.design.behavioral.state
#### 7 总结
多个状态 -> 状态模式解决 -> 借助 状态机 解决