设计模式
1、创建型-单例模式(Singleton)
意图
保证一个类只有一个实例,并提供一个访问他的全局访问点
六种实现
①懒汉模式-非线程安全
②饿汉模式-线程安全
③懒汉模式-线程安全
④双重校验锁-线程安全
⑤静态内部类实现-JVM保证线程安全
⑥枚举类实现-可以解决反射攻击
2、创建型-简单工厂模式(SimpleFactory)
意图
创建对象时不向客户暴露对象内部细节,并提供一个创建对象的通用接口
实现
接口以及实现接口的对象
通过client类中的getPro方法创建对象
3、创建型-工厂方法(Factory Method)
意图
定义了一个创建对象的接口,但由子类去决定具体实例化那个类(工厂方法与简单工厂的区别是,工厂方法创建实例由子类决定,而简单工厂由另一个类决定)
实现
4、创建型-抽象工厂(Abstract Factory)
意图
提供一个接口,用于创建相关对象家族
实现
相关对象家族
---------继承于-------------》
抽象工厂
子类实现
调用类
5、创建型-生成器(Builder)
意图
封装一个对象的构造过程,并允许按步骤构造
实现
StringBuilder的源码实现
6、创建型-原型模式(ProtoType)
意图
使用原型实例指定要创建对象的类型,通过复制这个原型来创建新的对象
实现
7、结构型-外观(Facade)
意图:
为系统中一组接口提供一个统一的界面。Faced模式定义可一个高层次的接口,这个接口使得这一子系统更加容易使用
适用场景
- 当你要为一个复杂的子系统提供一个简单的接口时。子系统往往会因为不断演化而变得越来越负载,大多其他的模式使用的时候都会产生其他许多小类,这使得那些不需要定制使用的用户使用起来非常的困难,这时候Faced可以为用户提供一个简单的缺省视图,这个视图对于大多数用户已经够用,而那些需要定制化的用户也可以轻易的绕过Faced层
- 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Faced可以将这个子系统与客户以及其他子系统分离,,可以提高子系统的独立性和可以移植性。
- 当你需要构建一个层次结构的子系统时,使用Faced模式定义子系统中每层的入口,如果层与层之间存在依赖,可以让他们通过Faced进行通信,从而简化他们的依赖关系
实现(模拟“看电影”):
- 子系统层
- Faced接口
- 用户调用
设计原则:
迪米特法则(最小知识原则):低耦合,高内聚,也就是说客户对象所需要交互的对象应当尽可能少
结构型-适配器(Adapter||Wrapper(包装器))
意图:
将一个类的接口转换成为客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
适用性:
- 想使用一个已存在的类,而他的接口并不符合你的要求
- 像创建一个可复用的类,该类可以与其他不相关的类或不可预见的类协同工作
- (仅适用于对象Adapter)你想使用一些已经存在的对象的部分子类,但是不可能对每个都进行子类化以匹配他们的接口。这时候对象适配器就可以用来适配他们的父类接口
实现:
一个鸭子假扮成火鸡!!!!
- 鸭子(父类)
- 火鸡(父类)
- 野生火鸡(实现类)
- 鸭子扮演用的工具(适配器)
- 测试
- 运行结果
结构型-桥接(Bridge)
意图:
将抽象部分与他的实现部分分离开来,使得他们可以独立的进行改变
适用性:
- 不希望抽象和他的实现之间有一个固定的绑定关系
- 类的抽象以及他的实现都应该可以通过生成子类的方法加以扩充
- 对一个抽象的实现部分的修改不应该对客户产生影响,即客户的代码不应该重新编译
- 当有许多类要生成时
- 想要在多个对象间共享实现,但同时要求客户并不知道
实现:
- 抽象方
- 抽象方实现
- 实现方
- 实现方实现
- 测试
- 结果
结构型-组合(Composite)
意图:
将对象组合成树形结构以表示“部分-整体”的关系,并且允许用户以相同的方式处理单独的对象或者组合对象
适用性:
- 想表示一个“部分-整体”的层次结构
- 希望用户忽略组合对象与整体对象的不同,用户将统一的使用组合结构中的所有对象
实现:
- 整体
- 部分(组合)
- 部分(叶子)
- 测试
- 结果
结构型-装饰(Decorator)
意图:动态的给对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类来说更加灵活
适用性:
- 在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责
- 处理那些可以被撤销的职责
- 当不能采用生成子类的方式进行扩展时,一种情况是,可能有大量的独立扩展,为支持每一种组合将生成大量的子类扩展,另一种情况是类定义被隐蔽或类定义不能用于生成子类。
实现:
装饰者(用于添加佐料)
- 测试
- 结果
结构型-享元(FlyWeight)
意图:运用共享技术有效的支持大量细粒度对象,且这些对象一部分内部状态是相同的
适用性:
- 一个应用程序使用了大量对象
- 完全由于使用大量对象造成了很大的开销
- 对象的大多数状态都可以变为外部状态
- 如果删除对象外部状态,那么可以用相对较少的共享对象取代很多组对象
- 应用程序不依赖于对象标识,因为Flyweight对象可以被共享,因此对于概念上有别的对象,标识检测将返回真值。
实现:
- 对象接口
- 对象实现
- 生成对象的工厂方法
- 测试
- 结果
对象的内部状态相同但是外部状态不同
结构型-代理(Proxy)
意图:
为其他对象提供一个代理以控制这个对象的访问
适用性:
- 远程代理:为一个对象在不同地址空间提供一个局部代表
- 虚拟代理:根据需要创建开销很大的对象,他可以缓存实体的附加信息,以便于延迟对他的访问,例如在网站要加载一个很大的图片,不能马上完成,可以使用户虚代理技术缓存图片大小信息,然后生成一张临时图片代替原图片
- 保护代理:控制对原始对象的访问,以达到保护原始对象的目的
- 智能代理:取代了简单指针,可以在访问对象时执行一些附加操作
实现:虚代理
- image接口
- 需要被加载的大图像
- 大图像的代理
- 测试
- 结果
行为型-责任链(Chain Of Responsibilities)
意图:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿这条链传递该请求,直到有一个对象能处理他为止。
适用性:
- 有多个对象可以同时处理一个请求时,那个对象处理该请求运行时自动确定
- 想在不明确指定接收者的情况下,向多个对象中的一个提交请求
- 可处理一个请求的对象集合应被动态指定
实现:
类图
- 模拟请求类
- 责任链集合抽象结构
- 抽象类实现
- 测试
- 运行结果
行为型-策略(Strategy)
意图:
定义一系列算法将他们封装起来,并且是他们可以相互替换,本模式使得算法可对立与使用他的客户变化
适用性:
- 许多相关的类仅仅是行为有异
- 需要使用一个算法的不同变体
- 算法使用客户不应当知道的数据
- 一个类定义了多种行为并且这些行为在这个类的操作中以多个条件语句的形式出现
实现:
- 行为接口
- 接口实现
- 用户可见对象
- 测试
- 结果
行为型-模板方法(Template Method)
意图:
定义一个操作中的算法骨架,而将一些实现步骤延迟到子类实现,该模式可以使得子类不改变一个算法的结构即可重新定义该算法的某些特定步骤
适用性:
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现
- 各子类中的公共行为应被提取出来并集中到一个父类中,以避免代码重复
- 控制子类扩展,模板方法只在特定点调用钩子操作,这样做就能做到只在这些点进行扩展
实现:喝茶和喝咖啡在步骤上基本相同,但是步骤实现却又明显区别
- 模板方法 抽象父类
- coffee实现
- tea实现
- 测试
- 运行结果
行为型-命令(Command)
意图:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队,记录请求日志,以及支持可撤销的操作
适用性:
- 抽象处待执行的动作,以参数化某个对象。
- 在不同的时刻指定、排列和执行请求
- 支持取消操作
- 支持修改日志,这样当系统崩溃时,这些修改可以被重新做一遍
- 用构建在原语操作上的高层操作构造一个系统
实现:
- ![940d2ff8fa33951918162a6613e5333a.png][940d2ff8fa33951918162a6613e5333a]
- ![7284a453cbfdbe8931c1c3fa29108efb.png][7284a453cbfdbe8931c1c3fa29108efb]
- ![af9dd493587c4d502445051fabde289c.png][af9dd493587c4d502445051fabde289c]
- ![112cc1258cf62de96b55cf1bd756ffdd.png][112cc1258cf62de96b55cf1bd756ffdd]
- ![568d00945e433c496421f5bd9903c867.png][568d00945e433c496421f5bd9903c867]
- ![5d4dd403dbe36e960f77278d0f986ab9.png][5d4dd403dbe36e960f77278d0f986ab9]
行为型-观察者(Observer)
意图:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖与他的对象都得到通知并被自动更新
适用性:
- 一个抽象模型又两方面,其中一个方面依赖与另一个方面。将二者封装在独立得对象中,使他们可以各自独立的改变和复用
- 对一个对象得改变需要同时改变其他对象,而不知道具体有多少对象待改变
- 一个对象必须通知其他对象,而他又不能假定其他对象是谁。换言之,不希望这些对象之间时紧密耦合得
实现:模拟气象站发布天气信息
- 观察者接口
- 观察者实现类
- 被观察者接口
- 被观察者实现类
- 测试
- 运行结果
行为型-访问者(visitor)
意图:
为一个对象结构(比如组合结构)增加新能力
适用性:
- 一个对象结构包含很多类对象,他们包含不同的接口,而你想对这些对象实施一些依赖于其具体类得操作
- 需要对一个对象结构中得对象进行很多不同并且不相关得操作,而你想避免让这些操作“污染这些对象得类”
- 定义对象结构的类很少改变,但需要经常在此结构上定义新的操作
实现:
- 对象结构
- 访问者
- 测试
- 结果
- 类图
行为型-状态(State)
意图:
允许一个对象在其内部状态改变时改变他的行为,对象看起来修改了他的类
适用性:
- 一个对象的行为取决于他的状态,并且需要在运行时根据状态改变他的行为
- 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于对象的状态,通常,有多个操作包含着一相同条件结构。State模式及那个一个条件分支放入一个独立的类中,这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖与其他对象而独立变化
实现:
- 状态接口
- 状态
- 糖果机类
- 测试类
- 结果
行为型-解释器(Expression)
意图:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
适用性:
当有一个语言需要解释执行,并且你可以将该语言中的句子表示成一个抽象语法树时,可使用该模式,一下情况效果最好
- 语法简单,对于复杂的文法文法的类层次会变得复杂而无法管理
- 效率并不是关键问题
实现:
- ![2fff2651a369c61f1d6bea188e5b7fff.png][2fff2651a369c61f1d6bea188e5b7fff]
- ![a51e0454ddf30dbb22bbb41be96b4c47.png][a51e0454ddf30dbb22bbb41be96b4c47]
- ![ab4f556c50d2345ce8d863f7f76af829.png][ab4f556c50d2345ce8d863f7f76af829]
- ![77bc596b4ab6d91f80d8aa5ac5da63db.png][77bc596b4ab6d91f80d8aa5ac5da63db]
- ![210e7c207094b003d7cb23371ce8f112.png][210e7c207094b003d7cb23371ce8f112]
行为型-迭代器(Iterator)
意图:
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露这个对象的内部表示
适用性:
- 访问一个聚合对象(形如List)的内容而无需暴露他的内部表示
- 支持对聚合对象的多种遍历
- 为遍历不同的聚合结构提供一个统一的接口
实现:
- 迭代器
- 聚合对象
- 测试
行为型-中介者(Mediator)
意图:
用一个中介对象来封装一系列对象的交互。中介者使各个对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变他们的交互
适用性:
- 一组对象以定义良好但复杂的方式通信,产生的交互方式混乱且难以理解
- 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象
- 想定制一个复用在多个类中的行为,而又不想生成太多子类
实现:
- 中介者
- 一组相互交互的对象
- 测试
- 结果
行为型**-备忘录(Memento)**
** ** 意图:
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象回复到原先保存的状态
适用性:
- 必须保存一个对象在某时刻的状态,这样以后需要时才能回复到先前的状态
- 如果一个接口让其他对象的到这个状态,将会暴露对象内部实现细节导致破坏封装性
实现:实现一个计算器功能,计算两个数字之和,并支持回滚(保存上一次计算的两个数字)
- <font style="font-size: 14pt;">备忘录</font>
- 计算器
- 测试
- 结果