导图社区 软件架构设计思维导图
学霸笔记分享!这份系统架构设计师第十一章软件架构设计思维导图必看!下图详细介绍了抽象工厂模式、代理模式、享元模式、装饰模式、备忘录模式、状态模式等二十三个设计模式。感兴趣的话,不要忘记给我点个赞哦!
编辑于2019-08-09 00:52:31软件架构设计
概述
概念
在特定场景下,用于解决一般设计问题的类和互相通信的对象的描述
对某一个问题的通用解决方案
组成
模式名称
问题
解决方案
效果
GoF 23个设计模式
创建型模式
工厂模式
抽象工厂模式
使用场景
系统的产品有多于一个的产品族,而系统只消费其中某一族的产品
解决问题
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
解决接口选择的问题,根据不同配置或上下文环境加载不同实例
模式描述
抽象工厂
具体工厂
抽象产品
具体产品
效果
实现对象可配置、动态的创建
提高产品移植性
原型
单例
解决问题
服务类,只有一个实例供其他程序使用
构件器
复杂对象构造
将一个复杂类的表示跟其构造相分离,使相同的构建构成能够得到不同的表示
结构型模式
适配器
桥接
问题场景
在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
模式描述
把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。
抽象类为shape
把draw的实现剥离出来,并单独实现
组合模式
装饰模式
问题场景
为类预设的功能不够强大,需要进行扩展
解决问题
扩展一个类经常使用继承方法,然后引入了静态特征,并随着扩展功能的增多,子类会膨胀
模式描述
将具体功能职责划分,同时继承装饰者模式
优缺点
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
使用场景
1、扩展一个类的功能。
2、动态增加功能,动态撤销。
外观模式 (中控模式)
问题场景
系统调用了很多子系统,需要了解每一个子系统的接口
解决问题
降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口
模式描述
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口
为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
优缺点
优点
1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。
缺点
不符合开闭原则,如果要改东西很麻烦,继承重写都不合适
使用场景
1、为复杂的模块或子系统提供外界访问的模块。 2、子系统相对独立。 3、预防低水平人员带来的风险。
享元模式
代理模式
解决问题
直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
直接访问对象时带来的问题
模式描述
实现与被代理类组合
优缺点
优点
1、职责清晰。 2、高扩展性。 3、智能化。
缺点
1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
使用场景
按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。
行为型模式
职责链模式
解决问题
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了
模式描述
拦截的类都实现统一接口
优缺点
优点
1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
缺点
1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错。
使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。
访问者模式
解决问题
稳定的数据结构和易变的操作耦合问题
实现方法
在被访问的类里面加一个对外提供接待访问者的接口
在数据基础类里面有一个方法接受访问者,将自身引用传入访问者
模式描述
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。
主要将数据结构与数据操作分离。
computerParts通过visit接口,允许vistor进行访问
优缺点
优点
1、符合单一职责原则。
2、优秀的扩展性。
3、灵活性
缺点
1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
使用场景
1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类
解释器模式
解决问题
对于一些固定文法构建一个解释句子的解释器
模式描述
构建语法树,定义终结符与非终结符
解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
构建环境类,包含解释器之外的一些全局信息,一般是 HashMap
TerminalExpression 是上下文中的主要解释器
OrExpression、AndExpression 用于创建组合式表达式
使用场景
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题
迭代器模式
解决问题
不同的方式来遍历整个整合对象。
模式描述
这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
把在元素之间游走的责任交给迭代器,而不是聚合对象。
中介者模式
解决问题
对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
实现方法
对象 Colleague 之间的通信封装到一个类中单独处理
网状结构分离为星型结构
模式描述
用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
优缺点
优点
优点: 1、降低了类的复杂度,将一对多转化成了一对一。 2、各个类之间的解耦。 3、符合迪米特原则。
缺点
缺点:中介者会庞大,变得复杂难以维护。
使用场景
1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。 2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
命令模式
解决问题
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适
在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
模式描述
一种数据驱动的设计模式
将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化
定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口
使用场景
认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。
观察者模式
解决问题
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
模式描述
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。
实现方法
在抽象类里有一个 ArrayList 存放观察者们
状态模式
解决问题
对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
实现方法
通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if...else 等条件选择语句
将各种具体的状态类抽象出来
模式描述
使用场景
代码中包含大量与对象状态有关的条件语句
策略模式
解决问题
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护
实现方法
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换
实现同一个接口
模式描述
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改
使用场景
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
模板方法模式
解决问题
一些方法通用,却在每一个子类都重新写了这一方法
实现方法
将这些通用算法抽象出来。
在抽象类实现,其他步骤在子类实现
模式描述
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
创建一个定义操作的 Game 抽象类,其中,模板方法设置为 final,这样它就不会被重写。Cricket 和 Football 是扩展了 Game 的实体类,它们重写了抽象类的方法。
使用场景
1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法
备忘录模式
解决问题
所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
模式描述
通过一个备忘录类专门存储对象状态
客户不与备忘录类耦合,与备忘录管理类耦合。
优缺点
优点
1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。 2、实现了信息的封装,使得用户不需要关心状态的保存细节
缺点
消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存
使用场景
1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。