导图社区 设计模式学习
设计模式的思维导图,学习中不断的总结。包括常见的,单例模式、观察者模式、工厂模式、建造者模式等等。
编辑于2023-03-28 00:07:00 上海Android设计模式学习
面向对象六大原则
单一职责原则
如何划分一个类、一个函数的职责
基本指导原则
两个完全不一样的功能就不应该放在一个类中
一个类中应该是一组相关性很高的函数、数据的封装
开闭原则
软件中的对象应该对于扩展是开放的,但是对于修改是闭合的
当软件需要变化时,应该尽量通过扩展的方式来实现变化,而不是通过修改已有的代码来实现
里氏替换原则
核心原理
抽象
引用基类的地方必须能透明地使用其子类的对象
父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常
通过里氏替换原则来达到对扩展开放,对修改关闭的效果
依赖倒置原则(依赖反转原则)
关键点
1、高层模块不应该依赖底层模块
2、抽象不应该依赖细节
Java中,抽象指接口或者抽象类。细节就是实现类,实现接口或继承抽象类而产生的类
3、细节应该依赖抽象
在Java语言中的表现
模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
面向接口编程
接口隔离原则(InterfaceSegregation Principles,ISP)
客户端不应该依赖它不需要的接口
只需要知道这个对象是可关闭,其他的一概不关心
SOLID原则
底米特原则
英文全称
Law of Demeter(LOD)最少知识原则
Only talk to your immedate friends 只与直接的朋友通信
原则
一个对象应该对其他对象有最少的了解
设计模式
共23种设计模式
单例模式
定义
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
重点,确保只有一个类
使用场景
确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有一个
关键点
1、构造函数不对外开放,一般为private
说明会暴露一个公有静态方法获取到单例类的唯一对象
2、通过一个静态方法或者枚举返回单例类对象
3、确保单例类的对象有且只有一个,尤其是在多线程环境下
4、确保单例类对象在反序列化时不会重新构建对象
模式
饿汉模式
声明静态对象时已经初始化了
样式
饿汉模式
懒汉模式
通过调用getInstance方法去进行实例化对象
getInstance方法使用了synchronized关键字修饰
缺点
即使instance已经被初始化了,但是每次使用getInstance的时候,都会进行同步,因此消耗了不必要的资源
第一次加载时需要及时地实例化,反应较慢
优点
单例只有在使用的时候才会被实例化
样式
懒汉模式
DLC模式(DoubleCheckLock模式)
使用得最多的单例初始化方式
会出现双重检查锁定失效
优点
需要时才实例化
资源利用率高
能够保证线程安全
单例对象初始化后调用getInstance不进行同步锁
缺点
第一次加载稍慢,由于Java内存模型偶尔会失败
高并发情况下会存在缺陷
样式
DLC模式
静态内部类模式
说明
只有在第一次调用内部类的方法的时候才会进行实例初始化
能够保证线程的安全,也能够保证单例对象的唯一,同时也延迟了单例的实例化
样式
静态内部类模式
枚举单例
最大的优点
创建是线程安全的,包括在序列化和反序列化的情况下
样式
枚举单例
Builder模式
简介
一步步创建一个复杂对象的创建型模型,允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程
使得解耦,让构建复杂的对象的过程和它的部件进行解耦
使用场景
1、相同的方法,不同的执行顺序,产生不同的结果
2、多个部件或者零件,都可以组装到一个对象中,但是产生的运行结果又不同
3、产品类非常复杂,产品类中的不同顺序会产生不同的结果
4、初始化一个对象特别复杂
UML
Builder模式的UML图
原型模式
说明
创建型的模型
“克隆”
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象
使用场景
1、类初始化需要消耗很多资源,通过原型拷贝避免消耗
2、通过new产生对象需要非常繁琐的数据准备或访问权限
3、保护性拷贝
UML
原型模式UML图
实现Cloneable接口
深拷贝
再拷贝对象的时候,对于引用型的字段也要采用拷贝的方式,而不是单纯的引用
可以做到完全拷贝
浅拷贝
影子拷贝
副文本使用源文本的字段
引用的地址相同
浅拷贝示意图
优点
在内存中形成二进制流的拷贝,比new的性能要好得多
减少了约束
初始化快,减少了约束
缺点
直接在内存中拷贝,不会执行其构造函数
减少了约束
不会执行构造函数,需要在开发中进行实际的考虑
工厂方法模式
说明
简单的构造模式,开发中用得非常的广泛
定义一个用于创建对象的接口,让子类来决定实例化哪个类
使用场景
需要构建复杂的对象都可以使用工厂模式
仅用new可以产生的对象无需使用
UML图
工厂方法模式的UML图
工厂类的抽象(利用了反射的思想)
反射思想
抽象工厂模式
说明
生产出来的产品是抽象的
为创建一组相关或相互依赖的对象提供一个接口,而不需要指定它们的具体类
UML
抽象工厂模式的UML图
缺点
会导致类的徒增
策略模式
说明
实现某一个功能可以有多种算法或者策略,我们根据实际情况选择不同的算法或者策略来完成该功能
将这些算法或者策略抽象出来,形成统一接口
策略模式让算法独立于使用它的客户而独立变化
策略模式具有较高的可扩展性,可维护性
主要用来分离算法,在相同的行为抽象下有不同的具体实现策略
使用场景
1、针对同一类型问题的多种处理方式,仅仅是具体行为有差别
2、需要安全地封装多种同一类型的操作时
3、出现同一抽象类有多个子类,而有需要用if-else或者switch-case进行选择子类的
UML
策略模式的UML图
优点
结构清晰明了、使用简单直观
耦合度相对而言较低,扩展方便
操作系统也更为彻底,数据更为安全
缺点
随着策略的增加,子类也会b变得繁多
状态模式
说明
状态模式中的行为是由状态来决定的,不同的状态下有不同的行为
状态模式和策略模式的结构几乎完全一样
状态模式的行为是平行的、不可替换的
策略模式的行为是彼此独立的、可相互替换的
状态模式把对象的行为包装在不同的状态对象里,每一个状态对象都有一个共同的抽象状态基类
状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变
使用场景
1、一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为
2、代码中包含大量与对象状态有关的条件语句
UML
状态模式的UML图
优点
将所有与一个特定的状态相关的行为放入一个对象中,它提供了一个更好的方法来组织与特定状态相关代码,将繁琐的判断状态转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性和可维护性
缺点
会导致系统类和对象的个数增加
责任链模式
详情
一个链式结构
具有很好的灵活性,每一个节点当作一个对象,每一个对象拥有不同的逻辑,直到有对象处理这个请求位置
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系
UML图
责任链UML图
说明
当下层处理不了,提交上层处理
责任链的每一个处理对象,只有两个行为,一是处理请求,二是将请求转移
优点
可以对请求者和处理者关系解耦,提高代码的灵活性
缺点
对链中请求处理者的遍历,如果处理者太多,那么遍历必定会影响性能
解释器模式
没理解
详情
提供了一种解释语言的语法或表达式的方式
UML图
解释器模式的UML图
命令模式
说明
行为型设计模式之一
不是一个很“规矩”的设计模式,比较灵活
将请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;对请求排队或记录请求日志,以及支持可撤销的操作
使用场景
1、需要支持取消操作
2、需要抽象出待执行的操作,然后以参数的形式提供出来,类似于过程设计中的回调机制。命令模式是回调机制的一个面向对象的一个替代品
3、需要支持事务操作
4、在不同的时刻指定、排列和执行请求
5、支持修改日志功能,当系统崩溃时,这些修改可以重新做一次
UML图
命令模式的UML图
观察者模式
说明
使用频率非常高,最常用的就是GUI系统
解耦:观察者和被观察者
定义了一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
Java中在jdk9以后,废弃了Observer、Obserable内置类型,原因有三点
1、不可序列化
2、不是线程安全的
3、支持事件模型的功能简单
使用场景
关联行为场景。关联行为是可拆分的,而不是“组合”关系
事件多级触控场景
跨系统的消息交换场景,如消息队列、事件总线的处理机制
UML图
观察者模式的UML图
对于上述UML图的说明
Subject
抽象主题,也就是被观察的角色,抽象主题角色把所有观察者对象的引用保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象
ConcreteSubject
具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发出通知,具体主题角色又叫做具体被观察者角色
Observer
抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知时更新自己
ConcreteObserver
具体的观察者,该角色实现抽象观察者角色所定义的更新接口,以便在主题的状态发生变化时更新自身的状态
总结
观察者模式主要的作用时对象解耦,将观察者和被观察者完全隔离,只依赖于Observer和Observable抽象
优点
观察者和被观察者之间是抽象耦合,应对业务变化
增强系统灵活性、可扩展性
缺点
应用观察者模式时,需要考虑以下开发效率和运行效率问题
程序中包含一个被观察者、多个观察者、开发和调试等内容会比较复杂
java中消息的通知默认是顺序执行的,如果一个观察者卡顿,会影响整体的执行效率,需要考虑到异步的情况
备忘录模式
说明
一种行为模式
用于保存对象当前状态,并且在此之后可以再次恢复到此状态
备忘录模式实现的方式需要保证被保存的对象状态不能被对象从外部访问,目的是为了保护好被保护对象的完整性以及内部实现不被透漏
定义
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,以后就可将该对象恢复到原先保存的状态
使用场景
1、需要保存某一个对象在某一个时刻的状态或部分状态
2、如果用接口来让其他对象得到这些状态,将会暴漏对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过中间对象可以间接访问其内部状态
UML图以及说明
UML图
备忘录模式UML图
说明
Originator
负责创建一个备忘录,可以记录、恢复自身的内部状态。同时Originator还可以根据需要决定Memento存储自身的那些内部状态
Memento
备忘录角色,用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento
Caretaker
负责存储备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象
优点
给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态
实现了信息的封装,使得用户不需要关心状态的保存细节
缺点
消耗资源
每一次的保存一定会消耗一些内存
迭代器模式
说明
游标模式
行为型设计模式之一
源于对容器的访问,在客户访问类与容器体之间插入了一个第三者
迭代器的定义
提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴露该对象的内部表示
UML图以及说明
UML图
迭代器模式UML示例图
说明
Iterator
迭代器接口,负责定义、访问和遍历元素接口
Concrete Iterator
具体迭代器类,主要是实现迭代器接口,并记录遍历位置
Aggregate
容器接口,负责提供创建具体迭代器角色的接口
Concrete Aggregate
具体的容器类,迭代器角色与该容器相连
优点
支持以不同的方式去遍历一个容器对象,也可以有多个遍历
弱化了容器类与遍历算法之间的关系
缺点
类的文件的增加
模板方法模式
说明
某些步骤的具体是未知的,某些步骤的实现是会随着环境的变化而改变的
封装流程
定义
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
使用场景
1、多个子类有公有的方法,并且逻辑基本相同时
2、重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
3、重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为
UML图与说明
UML图
模板方法模式的UML示例图
说明
AbsTemplate
抽象类,定义了一套算法框架
ConcreteImplA
具体实现类A
ConcreteImplB
具体实现类B
优点
封装不变部分,扩展可变部分
提取公共部分代码,便于维护
缺点
模板方法会带来代码阅读的难度,对让用户觉得难以理解
访问者模式
说明
是一种将数据操作与数据结构分离的设计模式
是最复杂的一个设计模式
使用频率不高
要求元素的类族要稳定
基本思想
软件中拥有一个由许多对象构成的、比较稳定的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象的访问。
访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的处理。
在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中会调用访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。
我们可以针对对象结构设计不同的访问者类来完成不同的操作,达到区别对待的效果。
定义
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作
使用场景
对象结构比较稳定,但经常需要在此对象结构上定义新的操作
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类
UML图
UML图示
访问者模式UML图
说明
Visitor
接口或者抽象类,它定义了对每一个元素访问的行为,它的参数就是可以访问的元素,他的方法个数理论上来讲与元素个数是一样的。
ConcreteVisitor
具体的访问者,他需要给出每一个元素类访问时所产生的具体行为
Element
元素接口或者抽象类,它定义了一个接受访问者accept的方法,其意义时指每一个元素都要可以被访问者访问
ElementA、ElementB
具体的元素类,它提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法
ObjectStructure
定义当中所提到的对象结构,对象结构是一个抽象表述,它内部管理了元素集合,并且可以迭代这些元素供访问者访问
示例图
访问者模式的示例图
优点
增加访问者很容易
各角色职责分离,符合单一职责原则
具有优秀的扩展性
使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化
灵活性
缺点
具体元素对访问者公布细节,违反了迪米特原则
具体元素变更时导致修改成本大
违反依赖倒置原则,为了达到“区别对待”而依赖了具体类,没有依赖抽象
中介者模式(Mediator Pattern)
和事佬
说明
代理模式
说明
委托模式
结构型设计模式
非常重要的模式
定义
为其他对象提供一种代理以控制对这个对象的访问
使用场景
当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。
UML图
代理模式的UML图
说明
Subject
抽象主题类,该类的主要职责是声明真实主题与代理的共同接口方法,该类既可以是一个抽象类也可以是一个接口。
RealSubject
真实主题类,该类也称为被委托类或被代理类,该类定义了代理所表示的真实对象,由其执行具体的业务逻辑方法,而客户类则通过代理类间接地调用真实主题类中定义的方法。
ProxySubject
代理类,该类也称为委托类或代理类,该类持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行,以此起到代理的作用。
Client
客户端,使用代理类的类型
两种代理模式
静态代理
代理者的代码由程序员自己或通过一些自动化工具生成固定的代码再对其进行编译,也就是说在我们的代码运行前代理类的class编译文件就己存在
静态代理则只能为给定接口下的实现类做代理,如果接口不同那么就需要重新定义不同代理类,较为复杂,但是静态代理更符合面向对象原则
动态代理
动态代理则与静态代理相反,通过反射机制动态地生成代理者的对象,也就是说我们在code阶段压根就不需要知道代理谁,代理谁我们将会在执行阶段决定
需要实现接口
InvocationHandler
实现接口函数
invoke
动态代理通过一个代理类来代理N多个被代理类,其实质是对代理者与被代理者进行解耦,使两者直接没有直接的耦合关系
四种形式
远程代理(Remote Proxy)
为某个对象在不同的内存地址空间提供局部代理。使系统可以将Server部分的实现隐藏,以便Client可以不必考虑Server的存在
虚拟代理(Virtual Proxy)
使用一个代理对象表示一个十分耗资源的对象并在真正需要时才创建
保护代理(Protection Proxy)
使用代理控制对原始对象的访问。该类型的代理常被用于原始对象有不同访问权限的情况
智能引用(Smart Reference)
在访问原始对象时执行一些自己的附加操作并对指向原始对象的引用计数
静态代理和动态代理都可以使用这四种形式
组合模式
简介
也称为:部分整体模式
结构设计模式之一
将一组相似的对象看作一个对象处理,并且根据一个树状结构来组合对象,然后提供一个统一的方法去方位相应的对象,以此忽略掉对象与对象集合之间的差别
部分概念
枝干构件:拥有分支的节点
根构件:位于树状结构顶部的枝干构件
叶子构件:为整个树状图的始端,最底下的位置
这是绘制的图形
使用场景
表示对象的部分-整体层次结构时
从一个整体中能够独立出部分模块或功能的场景
定义
将对象组合成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。(View 和 ViewGroup)
两种组合模式
透明的组合模式
将组合所使用的方法定义在抽象类中
样例图
安全的组合模式
将各自的方法定义在各自中
样例图
说明
Component
抽象根节点,为组合中的对象声明接口
可在递归结构中定义一个接口,用于访问一个父节点
Composite
定义有子节点的那些枝干节点的行为,存储子节点
在Component接口中实现子节点的有关操作
Leaf
表示组合中表示叶子节点对象。在组合中定义节点对象的行为
Client
通过Component接口操作组合节点的对象
简单实例
使用的是一个安全的设计模式
View
doSomething()
ViewGroup
doSomething()
addView()
removeView()
getChildAt()
图示
最后
组合模式与解释器模式有一定的类同。都是在迭代对象时涉及递归的调用。
组合模式所提供属性层次结构使得我们能够一视同仁地对待单个对象和对象集合,牺牲类的单一性原则换取而来。而且组合模式是通过继承来实现的,缺少弹性。
优点
清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让高层模块忽略了层次的差异,方便对整个层次结构进行控制
高层模块可以一致地使用一个组合构件或者其中的单个对象,简化了高层模块的代码
符合“开闭原则”
为树形结构的面向对象提供了一种灵活的解决方案
缺点
新增构件时不好对枝干中的构件类型进行限制,不能依赖类型系统加以约束
必须进行类型检查来进行实现。
适配器模式
介绍
将不兼容的两个类融合在一起
像极了粘合剂
定义
把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作
使用场景
系统需要使用现有的类,该类不符合系统的需要。(接口不兼容)
建立一个可以重复使用的类,用于一些彼此之间没有太大关联的类
需要一个统一的输出接口,输入不可知
模式图
类适配器模式图
介绍
目标接口需要 operation2,但是Adaptee中仅有operation3
适配器Adapter需要实现operation2,从而将Adaptee中的operation3转换为Target中需要的operation2
类说明
Target
目标角色,期待得到的接口
Adaptee
现在需要适配的接口
Adapter
适配器角色,核心
优缺点
优点
更好的复用性
更好的拓展性
缺点
过多使用适配器会让系统非常零乱,不易于整体把握
装饰模式
介绍
也成为“包装模式”
结构型设计模式之一
使用一种对客户端透明的方式来动态地扩展对象的功能,也是继承关系的一种替代方案
定义
动态地给一个对象添加一些额外的职责
使用场景
需要透明且动态地扩展类的功能时
模式图
装饰模式的模式图
说明
Component
抽象组件
ConcreteComponent
组件具体实现类
Decorator
抽象装饰者,为了装饰组件对象
ConcreteDecoratorA
装饰着具体实现类
ConcreteDecoratorB
装饰着具体实现类
Android中的例子
Activity
ContextThemeWrapper
ContextWrapper
该类中Keep Context,并且extend Context
Context
总结
装饰模式与代理模式相似,但是不同
装饰模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案
代理模式则是给一个对象提供一个代理对象,并有代理对象来控制原有对象的引用
装饰模式是为装饰的对象增强功能
代理模式是对代理对象施加控制,但不是对本身进行功能性的增强
享元模式
介绍
对象池的一种实现
英文名称:Flyweight 轻量级
可以尽可能减少内存使用量,适合用于存在大量重复对象的场景,来缓存可共享的对象,达到对象共享、避免创建过多对象的效果
共享状态
部分状态可共享,可以共享的状态称为内部状态,内部状态不会随着环境变化
不可共享的状态称为外部状态,它们会随着环境的改变而改变
定义
使用共享对象可有效地支持大量的细粒度地对象
使用场景
系统中存在大量地相似对象
细粒度地对象都具备较接近地外部状态,而内部状态与环境无关,也就是说对象没有特定身份。
需要缓冲池地场景
UML类图
图片样例
角色介绍
Flyweight
享元对象抽象基类或者接口
ConcreteFlyweight
具体的享元对象
FlyweightFactory
享元工厂,负责管理享元对象池和创建享元对象
简单例子
Handler中的Message
Message通过next串成一个可用的Message池,链表
创建的时候不会把Message放到池中,回收时才会将该对象放到池中
简单总结
享元模式实现比较简单,作用在某些场合极其重要,可以大大减少应用程序创建的对象,降低内存的占用
享元模式提高了系统的复杂性,需要分离出外部状态和内部状态,而且外部状态具备固化特性,不应该随着内部状态改变而改变
享元模式使得系统更加复杂,为了使对象可以共享,需要将一些状态外部化,使得程序的逻辑复杂化
享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长
外观模式
定义
要求一个子系统的外部与其内部的通信必须通过一个统一的对象继续宁。门面模式提供一个高层次的接口,使得子系统更易于使用
使用场景
为一个复杂子系统提供一个简单接口,对外隐藏子系统具体实现、隔离变化(子系统可能会演变的越来越复杂,或者被替换)
需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点,可以简化依赖关系
UML图
图片模型
角色介绍
Facade
系统对外的统一接口,系统内部系统地工作
SystemA、SystemB、SystemC
子系统接口
UML较为简单,通过一个统一的接口对外提供服务,使得外部程序只通过一个类就可以实现系统内的多种功能。通过外观类来对外屏蔽内部类中可能存在的复杂的交互,降低使用成本
样例
Android系统中的ContextImpl
总结
精髓在于封装
优点
对客户程序隐藏子系统细节,拥抱变化
外观类对子系统的接口封装,使得系统易于使用
缺点
外部类接口膨胀,可能会增加用户使用成本
外观类没有遵循开闭原则
桥接模式
介绍
也成为“桥梁模式”,结构型设计模式之一
定义
将抽象部分与实现部分分离,使它们都可以独立地继续变化
使用场景
任何多维度变化类或者多个树状类之间地耦合
系统需要构件地抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系
不希望使用继承或者因为多层次继承导致系统类的个数急剧增加的系统
一个类存在两个独立变化的维度,且这两个维度都需要进行扩展
UML图
图例
角色说明
Abstraction
抽象部分,一般为抽象类,保持一个对实现部分对象的引用
RefinedAbstraction
优化的抽象部分,对抽象部分的方法进行完善和扩展
Implementor
实现部分,可以为接口或者抽象类,方法不一定要与抽象部分中的一致,可以提供基本的操作,抽象部分定义的使基于实现部分这些基本操作的业务方法
ConcreteImplementorA/ConcreteImplementorB
实现部分的具体实现,完善实现部分(Implementor)中方法定义的具体逻辑
Client
客户类
总结
用的不多
需要有一个恰到好处的分寸
不容易设计
说明
思维导图中所有的内容均是基于《Android源码设计模式解析与实战》第一版所做