设计模式
参考
- https://www.yuque.com/saodai/ss8tp9
- B站视频
- 我这里只是个做个笔记,设计模式最好结合UML 类图并且结合实际代码学习,最好还是看上边视频中相关内容
- 创造型设计模式
- 概念:创造型设计模式抽象了实例化过程,帮助一个系统如何创建、组合、和表示那些对象
- 简单工厂模式:
1. 定义一个工厂类,可以根据传入的参数的不同,返回不同类的实例,这些“不同类”继承自同一个父类
2. 工厂类中创建实例的方法通常是一个静态方法,因此又称为静态工厂
3. 使用者无需知道产品对象是如何创建的 - 工厂方法模式(Factory Method):
1. 在简单工厂基础上,定义一个用于创建对象的工厂接口,让实现这个接口的子类来决定实例化哪个类,
2. 工厂方法模式使一个类的实例化延迟到了子类
3. 适用性:- 当一个类不知道它所必须创建的对象的类的时候
- 当一个类希望由他的子类来指定它所创建的对象的时候
- 抽象工厂模式(Abstract Factory):
1. 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类
2. 可以理解为:“工厂方法” 创建的是一中对象,“抽象工厂” 创建的是一系列对象
3. 适用性:- 一个系统要独立于它的产品创建、组合和表示时
- 一个系统要由多个产品系列中的一个来配置时
- 当要强调一系列相关产品对象的设计以便进行联合使用时
- 当提供一个产品类库,只想显示他们的接口而不是实现时
- 生成器模式(Builder):
1. 意图:将一个复杂对象的构建和他的表示分离,使得同样的构建过程可以创建不同的表示
2. 理解:定义一个抽象的生成器;再定义多个具体的生成器类(封装对象复杂的算法)来继承它;定义一个管理者(对象装配)来操作生成器,这样管理者与不同的生成器类组合就可以创建不同的产品表示
3. 适用性:- 当创建对象的复杂的算法应该独立于该对象的组成部分和装配方式时
- 当构造过程必须允许被构造对象有不同表示时
- 原型模式(Prototype)
1. 意图:用原型实例指定创建对象的种类,通过复制这些原型创建新的对象
2. 适用性:- 当一个系统应该独立于它的产品创建、构成和表示时
- 当要实例化的类是在运行时刻指定的,例如动态装载
- 当一个类的实例只能有几个不同状态组合中的一种,
- 单例模式(Singleton)
1. 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点
2. 适用性:- 当类只能有一个实例,且客户从一个众所周知的访问点访问它时
- 结构型设计模式
- 概念:涉及如何组合类和对象,以获得更大的结构
- 适配器模式(Adapter)
1. 意图:将一个类的接口转换成用户希望的另一个接口,使得原本由于接口不兼容不能一起工作的哪些类可以一起工作
2. 适用性:- 想使用一个已存在的类,但是接口不符合要求
- 桥接模式(Bridge):
1. 意图:将抽象部分与实现部分分离,使他们都可以独立的变化
2. 理解:通过聚合或组合关系,将一个有多种组合情况的类拆分成几个相互关联的类,这个每个类各自可以独立变化
3. 适用性:- 不希望在抽象和他的实现部分之间有一个固定的绑定关系
- 类的抽象和它的实现都可以通过生成子类的方法加以扩充
- 对抽象的实现部分的修改应该对客户不产生影响,不必重新编译
- 有许多类要生成的类层次结构
- 组合模式(Composite)
1. 意图:将对象组合成树型结构,以表示 部分–整体 的层次结构,使得用户对单个对象和组合对象的使用具有一致性
2. 理解:以文件夹与文件间的关系去理解
3. 适用性:- 想要表示对象的部分–整体层次结构
- 希望用户忽略组合对象与单个对象间的不同,统一的使用组合中的所有对象、
- 装饰器模式(Decorator)
1. 意图:动态的给一个类添加一些额外的职责
2. 适用性:- 在不影响其他对象的情况下,动态透明的方式给单个对象添加职责
- 处理那些可以撤销的职责
- 当不能采用生成子类的方式进行扩充时
- 外观模式(Facade)
1. 意图:为子系统中的一组接口提供一个一致的界面,定义一个高层接口,使得子系统更加容易使用
2. 适用性:- 要为一个复杂的子系统提供一个简单的接口时
- 客户程序与抽象类的实现部分之间存在很大的依赖性
- 当需要构建一个层次结构的子系统时,使用外观模式定义子系统每层的入口点
- 享元模式(Flyweight)
1. 意图:运用共享技术,有效的支持大量细粒度的对象
2. 理解:用一个享元工厂来创建并维护实例,一种实例只创建一个,后续创建都是直接返回已创建的实例
3. 适用性:- 一个应用程序使用了大量的对象
- 由于使用了大量的对象,造成了很大的存储开销
- 对象的大多数状态都可以变为外部状态
- 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
- 代理模式(Proxy)
1. 理解:为其他对象提供一种代理,以控制对这个对象的访问
2. 适用性:- 在需要比较通用和复杂的对象指针代替简单的指针的时候
- 行为型设计模式
- 概念:涉及算法和对象间职责的分配,描述了它们之间的通信模式,使用继承机制在对象间分配行为
- 责任链模式(Chain of Responsibility):
1. 意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将对象连城一条链,沿着链传递请求,直到有一个对象处理它为止
2. 适用性:- 有多个对象处理一个请求,哪个对象处理该请求在运行时自动确定
- 想在不明确指定接受者的前提下向多个对象中的一个提交请求
- 可处理一个请求的对象集合被应动态指定
- 命令模式(Command)
1. 意图:将一个请求封装成一个对象,从而使得可以用不同的请求对客户进行参数化,对请求排队、记录请求日志、以及支持可撤销的操作
2. 适用性:- 抽象出待执行的动作以参数化某对象
- 在不同的时刻指定、排列和执行请求
- 支持取消操作、修改日志
- 解释器模式(Interpreter)
1. 意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,解释语言中的句子
2. 适用性:- 当一个语言需要解释执行时,可将语言中的句子表现为一个抽象语法树
- 迭代器模式(Iterator)
1. 意图:提供一种方法顺序的访问一个聚合对象中的各个元素,且不需要暴露该对象的内部表示
2. 适用性:- 访问一个聚合对象的内容而无需暴露它的内部表示
- 支持对聚合对象的多种遍历
- 为遍历不同的聚合结构提供一个统一的接口
- 中介模式(Mediator)
3. 意图:用一个中介对象来封装一系列的对象交互,中介者使得各个对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互
4. 适用性:- 一组对象定义良好,但是以复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解
- 备忘录模式(Memento)
1. 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在对象之外保存,这样以后就可以将对象恢复到原先保存的状态
2. 适用性:- 必须保存一个对象在某一时刻的(部分)状态,这样以后在需要时才能恢复之前的状态
- 如果用一个接口来让其他对象直接得到这些状态,将会暴露对象的实现细节,并破坏对象的封装性
- 观察者模式(Observer)
1. 意图:定义对象间的一对多的依赖关系,当一个对象发生改变时,所有依赖它的对象都得到通知,并自动更新
2. 适用性- 当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象待改变时
- 当一个对象必须通知其他对象,而它又不能假定其他对象是谁,即不希望这些对象是紧耦合的
- 状态模式(State)
1. 意图:允许一个对象再其内部状态改变时改变它的行为,对象似乎修改了它的类
2. 适用性:- 一个对象的行为决定于它的状态,并且必须在运行时刻根据状态改变它的行为
- 一个操作中含有庞大的多分支条件语句,这些分支依赖于该对象的状态。
- 策略模式(Strategy)
1. 意图:定义一系列算法,把他们一个个封装起来,并使得他们可以相互替换,此模式使得算法可以独立于使用他们的客户而变化
2. 适用性:- 许多相关的类仅仅是行为有异,策略提供了一种用多个行为中的一个行为来配置一个类的方法
- 需要使用一个算法的不同变体
- 使用算法的客户不应该知道数据结构,避免暴露
- 一个类中定义了多种行为,这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入他们各自的策略类中,以代替这些条件语句
- 模板方法(Template Method)
1. 定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得一个子类可以不改变一个算法的结构即可重新定义该算法的某些步骤
2. 适用性- 一次性实现一个算法的不变的部分,并将可变的行为留给子类实现
- 各子类中的公共行为应被提取出来并集中到一个公共的父类,以避免代码重复
- 控制子类扩展,模板方法仅允许在特定点进行扩展
- 访问者模式(Visitor)
1. 意图:表示一个作用于某对象结构中的各元素的操作。允许在不改变各元素类的前提下,定义作用于这些元素的新操作
2. 适用性:- 一个对象结构包含很多类对象,他们有不同的接口,而用户想对这些对象实施一些依赖于其具体类的操作
- 需要对一个对象结构中的对象,进行很多不同的并且不相关的操作,而有不想这些操作污染这些对象的类
- 定义对象的类很少改变,但经常需要在此结构上定义新的操作