设计原则
- 找出应用中可能出现的变化,把它们独立出来,不要和不变的混在一起
- 针对接口编程而不是针对实现编程(变量的声明是超类型—抽象类或接口)
- 多用组合 少用继承
- 为了交互对象之间的松耦合设计而努力
- 类应该对拓展开放、对修改关闭
- 依赖倒置原则:要依赖抽象,不依赖实现
- 好莱坞原则:别调用(打电话给)我们,我们会调用(打电话给)你。
策略模式
- 策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户
- (使用一个超类统一相同点,使用一个接口抽象不同点,然后在超类中组合这个接口,让接口的各个实现类封装变化)
例如:
将 鸭子duck的 行为 fly、quack 抽象出来,父类中添加接口引用 组合使用 ,提供通用的方法 preformXX()调用接口执行操作,添加setXX方法,使类能支持动态改变行为
关键词:Strategy
模式结构
策略模式的结构包括三种角色:
(1)策略(Strategy):策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法。
(2)具体策略(ConcreteStrategy):具体策略是实现策略接口的类。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。
(3)上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。
适用场景
- 一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式在类中使用大量的条件语句
- 程序不希望暴露复杂的、与算法有关的数据结构,那么可以使用策略模式来封装算法
- 需要使用一个算法的不同变体
观察者模式
出版者+订阅者=观察者模式
观察者模式是关于多个对象想知道一个对象中数据变化情况的一种成熟的模式。观察者模式中有一个称作“主题”的对象和若干个称作“观察者”的对象,“主题”和“观察者”间是一种一对多的依赖关系,当“主题”的状态发生变化时,所有“观察者”都得到通知
定义对象之间的一种一对多依赖关系,使得每一个对象发生状态的变化时,其相关依赖对象皆得到通知并被自动更新,又称为发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependence)模式。
例如
天气数据抽象出 主题Subject接口,布告板作为观察者,抽象出 Observer接口 统一调用方法update ,观察者对象持有subject引用,方便注册删除,
关键词:Subject,Observer,Concrete
模式结构
(1)主题(Subject):主题是一个接口,该接口规定了具体主题需要实现的方法,比如,添加、删除观察者以及通知观察者更新数据的方法。
(2)观察者(Observer):观察者是一个接口,该接口规定了具体观察者用来更新数据的方法。
(3)具体主题(ConcreteSubject):具体主题是实现主题接口类的一个实例,该实例包含有可以经常发生变化的数据。具体主题需使用一个集合,比如ArrayList,存放观察者的引用,以便数据变化时通知具体观察者。
(4)具体观察者(ConcreteObserver):具体观察者是实现观察者接口类的一个实例。具体观察者包含有可以存放具体主题引用的主题接口变量,以便具体观察者让具体主题将自己的引用添加到具体主题的集合中,使自己成为它的观察者,或让这个具体主题将自己从具体主题的集合中删除,使自己不再是它的观察者。
适用场景
(1)当一个对象的数据更新时需要通知其他对象,但这个对象又不希望和被通知的那些对象形成紧耦合。
(2)当一个对象的数据更新时,这个对象需要让其他对象也各自更新自己的数据,但这个对象不知道具体有多少对象需要更新数据
装饰者模式
装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。在装饰模式中,“具体组件”类和“具体装饰”类是该模式中最重要的两个角色。“具体组件”类的实例称作“被装饰者”,“具体装饰”类的实例称为“装饰者”。“具体装饰”类需要包含有“具体组件”类的一个实例的引用,以便装饰“被装饰者”
关键词 Decorator
例如 饮料 有 家庭口味、黑咖啡、浓缩咖啡、无咖啡因咖啡, 提供一个调料 装饰者Decorator,调料持有饮料对象,实现各自的拓展方法
模式结构
(1)抽象组件(Component):抽象组件是一个抽象类。抽象组件定义了“被装饰者”需要进行“装饰“的方法。
(2)具体组件(ConcreteComponent):具体组件是抽象组件的一个子类,具体组件的实例称为“被装饰者“。
(3)装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包含一个抽象组件声明的变量以保存“被装饰者“的引用。装饰可以是一个抽象类也可以是一个非抽象类,如果是非抽象类,该类的实例称为”装饰者“。
(4)具体装饰(ConcreteDecorator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称为“装饰者“。
适用场景(替代继承)
(1)程序希望动态地增强类的某个对象的功能,而又不影响到该类的其他对象。
(2)采用继承来增强对象功能不利于系统的扩展和维护。
工厂模式
关键词 factory
简单工厂模式
仅仅是把创建的判断逻辑单独拿出来放到一个工厂创建类中—-作为编程习惯
可以把create方法定义成 static,直接SimpleFactory.create调用,如果不是静态模式,可以在client开放构造方法,将factory对象传入使用
工厂(方法)模式
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
由于简单工厂方法 每增加一种 就要更改factory逻辑,所以 将其抽象处理(接口或者abstract),让子类(具体工厂)去创建
例如
建立工厂接口,建立 苹果,香蕉,橘子系列工厂,分片生产这些主原料对应的系列冰激凌
客户端 只需要 关注: 由‘工厂’创建‘产品’,客户端指名那个工厂去生产,但不与产品产生耦合,
(1)使用工厂方法可以让用户的代码和某个特定类的子类的代码解耦。
(2)工厂方法使用用户不必知道它所使用的对象是怎样被创建的,只需知道该对象有哪些方法即可。
工厂方法适合场景
(1)用户需要一个类的子类的实例,但不希望与该类的子类形成耦合。
(2)用户需要一个类的子类的实例,但用户不知道该类有哪些子类可用。
抽象工厂模式
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
(1)抽象工厂可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱耦。
(2)使用抽象工厂模式可以方便为用户创建一系列对象。用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不用系列中对象。
(3)在抽象工厂模式中,可以随时增加“具体工厂”为用户提供一组相关的对象。
工厂模式理解示例
简单工厂模式
比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标
工厂模式
工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。
戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。
生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。
后续直接调用鼠标工厂.生产鼠标()即可
抽象工厂模式
抽象工厂模式也就是不仅生产鼠标,同时生产键盘。
也就是PC厂商是个父类,有生产鼠标,生产键盘两个接口。
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
创建工厂时,由戴尔工厂创建。
后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。
抽象工厂—增加一个工厂
假设我们增加华硕工厂,则我们需要增加华硕工厂,和戴尔工厂一样,继承PC厂商。
之后创建华硕鼠标,继承鼠标类。创建华硕键盘,继承键盘类。
即可。
抽象工厂—增加一个产品
假设我们增加耳麦这个产品,则首先我们需要增加耳麦这个父类,再加上戴尔耳麦,惠普耳麦这两个子类。
之后在PC厂商这个父类中,增加生产耳麦的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳麦,惠普耳麦的功能。
单例模式-关键词Singleton
为了避免未知问题,只使用 俄汉式 以及枚举式,
饿汉式
饿汉式-静态代码块
懒汉式-双重检查
懒汉式-静态内部类
单元素枚举式
命令模式
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
比如 遥控器操作 灯 和电视机开关,将 具体receive对象封装为command对象,通过控制器 control来操作ccommand对象,从而达到请求者与执行者的解耦
关键词 Invoker、Handler、Receiver
模式结构
命令模式的结构中包括四种角色:
(1)接收者(Receiver):接收者是一个类的实例,该实例负责执行与请求者相关的操作。
(2)命令接口(Command):命令是一个接口,规定了用来封装“请求”的若干个方法,比如,execute()、undo()等方法。
(3)具体命令(ConcreteCommand):具体命令是实现命令接口的类的实例。具体命令必须实现命令接口中的方法,比如execute()方法,是该方法封装一个“请求”。
(4)请求者(Invoker):请求者是一个包含Command接口变量的类的实例。请求者中的Command接口的变量可以存放任何具体命令的引用。请求者负责调用具体命令,让具体命令执行那些封装了“请求”的方法,比如execute()方法。
适用场景
(1)程序需要在不同的时刻指定、排列和执行请求。(队列请求,日志请求)
(2)程序需要提供撤销操作。
(3)程序需要支持宏操作(宏命令是一个具体命令,不过它包含了其他具体命令的引用。即执行一个宏命令,相当于执行了许多具体命令)
适配器模式
适配器模式将一个类的接口,转换成客户期望的另个接口。适配器让原本接口不兼容的类可以合作无间。
关键词-adapter
模式结构
1)目标(Target):目标是一个接口,该接口是客户想使用的接口。
(2)被适配者(Adaptee):被适配者是一个已存在的接口或者抽象类,这个接口或者抽象类需要适配。
(3)适配器(Adapter):适配器是一个类,该类实现了目标接口并包含有被适配者的应用,即适配器的职责是对被适配者接口与目标接口进行适配。
适用场景
(1)一个程序想使用已经存在的类,但该类所实现的接口和当前程序所使用的接口不一致
外观模式
为系统中的一组接口提供一个一致的界面,Facade(外观)模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
关键词-facade
模式结构
适用场景
1)对于一个复杂的子系统,需要为用户提供一个简单的交互操作。
(2)不希望客户代码和子系统中的类有耦合,以便提高子系统的独立性和可移植性。
(3)当整个系统需要构建一个层次结构的子系。
装饰、适配、外观 特性区别
适配器模式:将一个或多个类接口变成客户所期望的一个接口。
外观模式:针对一个或多个复杂的类提供简化的接口。
两种模式的差异,不在于它们“包装”了几个类,而是在于它们的意图。
适配器模式意图:“改变”接口符合客户的期望。
外观模式意图:提供子系统的一个简化接口。
模板模式
定义了一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
关键词 template
模式结构
(1)抽象模板(Abstract Template):抽象模板是一个抽象类。抽象模板定义了若干个方法以表示算法的各个步骤,这些方法中有抽象方法也有非抽象方法,其中的抽象方法称为原语操作(Primitive Operation)。重要的一点是,抽象模板中还定义了一个称之为模板方法的方法,该方法不仅包含有抽象模板中表示算法步骤的方法调用,而且也可以包含有定义在抽象模板中的其他对象的方法调用,即模板方法定义了算法的骨架。
(2)具体模板(Concrete Template):具体模板是抽象模板的子类,实现抽象模板中的原语操作。
适用场景
1)设计者需要给出一个算法的固定步骤,并将某些步骤的具体实现留给子类来实现。
(2)需要对代码进行重构,将各个子类公共行为提取出来集中到一个共同的父类中以避免代码重复。
模板方法、策略、工厂方法 区别
迭代器模式
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露对象的内部表示。这就是迭代器模式的定义
关键词-iterator
模式结构
迭代器模式的结构中包括四种角色:
(1)集合(Aggregate):一个接口,规定了具体集合需实现的操作。
(2)具体集合(ConcreteAggregate):具体集合是实现集合接口的类的实例,具体集合按照一定的结构存储对象。具体集合应当有一个方法,该方法返回一个针对该集合的具体迭代器。
(3)迭代器(Iterator):一个接口,规定了遍历集合的方法,比如next()方法。
(4)具体迭代器(ConcreteIterator):实现迭代器接口的类的实例,具体迭代器在实现迭代器接口所规定的遍历集合的方法时,比如next()方法,要保证next()方法的首次调用即按照集合的数据结构找到该集合中的一个对象,而且每当找到集合中的一个对象,立刻根据该集合的存储结构得到待遍历的后继对象的引用,并保证依次调用next()方法可以遍历集合。
适用场景
(1)让用户访问一个集合中对象,但不想暴露对象在集合中的存储结构。
(2)希望对遍历不同的集合提供一个统一的接口。
很少用,除非自己封装了一个对象,里面又使用了各种集合,这种比较适合
组合模式
将对象组合成树形结构以表示“部分-整体”的层次结构。组合(Composite)使用户对单个对象和组合对象的使用具有一致性
关键词-composite、Leaf
模式结构
(1)抽象组件(Component):是一个接口(抽象类),该接口(抽象类)定义了个体对象和组合对象需要实现的关于操作其子节点的方法,比如add()、remove()以及getChild()等方法。抽象组件也可以定义个体对象和组合对象用于操作其自身的方法,比如isLeaf()。
(2)Composite节点(Composite Node):实现Component接口(或者抽象类)类的实例,Composite节点不仅实现Component接口,而且可以含有其他Composite节点或Leaf节点的引用。
(3)Leaf节点(Leaf Node):实现Component接口(或抽象类)类的实例,Leaf节点实现Component接口,不可以含有其他Composite节点或Leaf节点的引用,因此,叶节点在实现Component接口有关操作子节点的方法时,比如add()、remove()和getChild()方法,可让方法抛出一个异常,也可以实现为空操作。
适用场景
(1)当想表示对象的部分-整体层次结构。
(2)希望用户用一致的方式处理个体对象和组合对象。
状态模式
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类
在状态模式中,环境(Context)中不必出现大量的条件判断语句。环境(Context)实例所呈现的状态变得更加清晰、容易理解
关键词-state
模式结构
context:定义或者传入state状态,状态持有context自身
适用场景
(1)一个对象的行为依赖于它的状态,并且它必须在运行时根据状态改变它的行为。
(2)需要编写大量的条件分支语句来决定一个操作的行为,而且这些条件恰好表示对象的一种状态。
代理模式
当用户希望和某个对象打交道,但程序可能不希望用户直接访问该对象,而是提供一个特殊的对象,这个特殊的对象被称作当前用户要访问对象的代理,程序让用户和对象的代理打交道,即让用户通过访问代理来访问想要访问的对象
关键词-proxy
模式结构
适用场景
(1)程序可能不希望用户直接访问该对象,而是提供一个特殊的对象以控制对当前对象的访问。
(2)如果一个对象(例如很大的图像)需要很长时间才能加载完成。
(3)如果对象位于远程主机上,需要为用户提供访问该远程对象的能力。
责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
关键词-handler
模式结构
适用场景
(1)有许多对象可以处理用户的请求,希望程序在运行期间自动确定处理用户的那个对象。
(2)希望用户不必明确指定接受者的情况下,向多个接受者的一个提交请求。
(3)程序希望动态制定可处理用户请求的对象集合。
中介者模式
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
关键词-Mediator
1)中介者(Mediator):中介者是一个接口,该接口定义了用于同事对象之间进行通信的方法。
(2)具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信请求。
(3)同事(Colleague):一个接口,规定了具体同事需要实现的方法。
(4)具体同事(ConcreteColleague):实现同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需要将自己的请求通知给它所包含的具体中介者即可。
模式结构
适用场景
(1)许多对象以复杂的方式交互,所导致的依赖关系使系统难以理解和维护。
(2)一个对象引用其他很多对象,导致难以复用该对象。
建造者模式(生成器)
将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示
关键词-Builder
生成器模式结构中包括四种角色:
(1)产品(Product):具体生产器要构造的复杂对象;
(2)抽象生成器(Bulider):抽象生成器是一个接口,该接口除了为创建一个Product对象的各个组件定义了若干个方法之外,还要定义返回Product对象的方法;
(3)具体生产器(ConcreteProduct):实现Builder接口的类,具体生成器将实现Builder接口所定义的方法;
(4)指挥者(Director):指挥者是一个类,该类需要含有Builder接口声明的变量。指挥者的职责是负责向用户提供具体生成器,即指挥者将请求具体生成器类来构造用户所需要的Product对象,如果所请求的具体生成器成功地构造出Product对象,指挥者就可以让该具体生产器返回所构造的Product对象。
模式结构
适用场景
1)当系统准备为用户提供一个内部结构复杂的对象,而且在构造方法中编写创建该对象的代码无法满足用户需求时,就可以使用生成器模式来构造这样的对象。
(2)当某些系统要求对象的构造过程必须独立于创建该对象的类时。
原型模式
用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象
关键词-Prototype
原型模式结构包括两种角色:
(1)抽象原型(Prototype):一个接口,负责定义对象复制自身的方法。
(2)具体原型(ConcretePrototype):实现Prototype接口的类,具体原型实现抽象原型中的方法,以便所创建的对象调用该方法复制自己。
模式结构
适用场景
(1)程序需要从一个对象出发,得到若干个和其状态相同,并可独立变化其状态的对象时。
(2)当对象的创建需要独立于它的构造过程和表示时。
(3)一个类创建实例状态不是很多,那么就可以将这个类的一个实例定义为原型,那么通过复制该原型得到新的实例可能比重新使用类的构造方法创建新实例更方便。
桥接模式
关键词
桥接模式包括以下四种角色:
(1)抽象(Abstration):是一个抽象类,该抽象类含有Implementor声明的变量,即维护一个Implementor类型对象。
(2)实现者(Implementor):实现者角色是一个接口(抽象类),该接口(抽象类)中的方法不一定与Abstration类中方法一致。Implementor接口(抽象类)负责定义基本操作,而Abstration类负责定义基于这些基本操作的较高层次的操作。
(3)细化抽象(Refined Abstration):细化抽象是抽象角色的一个子类,该子类在重写(覆盖)抽象角色中的抽象方法时,在给出一些必要的操作后,将委托所维护Implementor类型对象调用相应的方法。
(4)具体实现者(Concrete Implementor):具体实现者是实现(扩展)Implementor接口(抽象类)的类。
模式结构
适用场景
(1)不想让抽象和某些重要的实现代码是固定绑定关系,这部分实现可运行时动态决定。
(2)抽象和实现者都可以继承的方法独立地扩充而互不影响,程序在运行期间可能需要动态的将一个抽象的子类的实例与一个实现者的子类的实例进行组合。
(3)希望对实现者层次的代码的修改对抽象层不产生影响,即抽象层的代码不必重新编译,反之亦然。
享元模式
一个类中的成员变量表明该类所创建对象所具有的属性,在某些程序设计中可能用一个类创建若干个对象,但是发现这些对象的一个共同特点是它们有一部分属性的取值必须是完全相同的。运用共享技术有效地支持大量细粒度的对象
关键词-Flyweight
模式结构
(1)享元接口(Flyweight):是一个接口,该接口定义了享元对外公开其内部数据的方法,以及享元接收外部数据的方法。
(2)具体享元(Concrete Flyweight):实现享元接口的类,该类的实例称为享元对象,或简称享元。具体享元类的成员变量为享元对象的内部状态,享元对象的内部状态必须与所处的周围环境无关,即要保证使用享元对象的应用程序无法更改享元的内部状态,只有这样才能使享元对象在系统中被共享。因为享元对象是用来共享的,所以不能允许用户各自地使用具体享元类来创建对象,这样就无法达到共享的目的,因为不同用户用具体享元类创建的对象显然是不同的,所以,具体享元类的构造方法必须是private的,其目的是不允许用户程序直接使用具体享元类来创建享元对象,创建和管理享元对象有享元工厂负责。
(3)享元工厂(Flyweight Factory):享元工厂是一个类,该类的实例负责创建和管理享元对象,用户或其他对象必须请求享元工厂为它得到一个享元对象。享元工厂可以通过一个散列表(也称作共享池)来管理享元对象,当用户程序或其他若干个对象向享元工厂请求一个享元对象时,如果享元工厂的散列表中已有这样的享元对象,享元工厂就提供这个享元对象给请求者,否则就创建一个享元对象添加到散列表中,同时将该享元对象提供给请求者。显然,当若干个用于或对象请求享元工厂提供一个享元对象时,第一个用户获得该享元对象的时间可能慢一些,但是后继的用户会较快地获得这个享元对象。可以使用单例模式来设计这个享元工厂,即让系统中只有一个享元工厂的实例,另外,为了让享元工厂能生成享元对象,需要将具体享元类作为享元工厂的内部类。
适用场景
(1)一个应用程序使用大量的对象,这些对象之间部分属性本质上是相同的,这时应使用享元来封装相同的部分。
(2)对象的多数状态都可改变为外部状态,就可以考虑将这样对象作为系统中的享元来使用。
访问者模式
表示将一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下定义作用于这些元素的新操作
关键词-Visitor
模式结构
访问者模式包括以下五种角色:
(1)抽象元素(Element):一个抽象类,该类定义了接受访问者的accept操作。
(2)具体元素(Concrete Element):Element的子类。
(3)对象结构(Object Structure):一个集合,用于存放Element对象,提供遍历它自己的方法。
(4)抽象访问者(Visitor):一个接口,该接口定义操作对象(Concrete Element的实例)的方法。
(5)具体访问者(Concrete Visitor):实现Visitor接口的类。
适用场景
(1)一个对象结构中,比如某个集合中,包含有很多对象,想对集合中对象增加新的操作。
(2)需要对集合中的对象进行很多不同并且不相关的操作,而又不想修改对象的类,就可以使用访问者模式。访问者模式可以在Visitor类中集中定义一些关于集合中对象的操作。
备忘录模式
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。这就是备忘录模式的定义。<br /> 对象的状态依赖于它的变量的取值情况,对象在程序运行期间的各个时刻可能具有不同的状态。在某些应用中,程序可能需要使用一种合理的方式来保存对象在某一时刻的状态,以便在需要时,对象能恢复到原先保存的状态。在备忘录模式中,称需要保存状态的对象为“原发者”,称负责保存原发者状态的对象为“备忘录”,称负责管理备忘录的对象为“负责人”
关键词-Memento,Caretaker
模式结构
备忘录模式包括以下三种角色:
(1)原发者(Originator):需要在某个时刻保存其状态的对象。原发者负责创建备忘录,比如使用createMemento()方法创建一个备忘录,然后原发者使用该备忘录记录自己的状态。当原发者需要恢复到某个状态时,它通过获取备忘录中相应的数据来恢复到那一时刻的状态,比如原发者调用restoreFromMemento(Memento mem)方法,并通过参数mem指定备忘录恢复状态。
(2)备忘录(Memento):负责存储原发者状态的对象,创建备忘录的类和创建原发者的类在同一个包中,该类提供的访问数据的方法都是友好方法,使得只有原发者在用一个包中的类的实例才可以访问备忘录中的数据。
(3)负责人(Caretaker):负责管理保存备忘录中的对象。负责人如果不和原发者在同一个包中就不能对备忘录中的内容进行修改或读取。如果需要将备忘录保存到磁盘,负责人可以使用对象流将备忘录写入文件。
适用场景
(1)必须保存一个对象在某一时刻的全部或部分状态,以便在需要时恢复该对象先前的状态。
(2)一个对象不想通过提供public权限的,诸如getXXX()的方法让其他对象得到自己的内部状态。
解释器模式
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
关键词-Expression
模式结构
1)抽象表达式(AbstractExpression):该角色是一个接口,负责定义抽象的解释操作。
(2)终结符表达式(TerminalExpression):实现AbstractExpression接口的类。该类将接口中的解释操作实现为与文法中的终结符相关联的操作,即文法中每个终结符号需要一个TerminalExpression类。
(3)非终结符表达式(NonterminalExpression):实现AbstractExpression接口的类。文法中的每一条规则都需要一个NonterminalExpression类。NonterminalExpression类为文法中的非终结符号实现解释操作,该解释操作通常使用递归调用表示文法规则中的那些对象的解释操作。
(4)上下文(Context):包含解释器之外的一些全局信息。
适用场景
当有一个简单的语言需要解释执行,并且可以将该语言的每一个规则表示为一个类时,就可以使用解释器模式
总结
创建型
1)工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
(2)抽象工厂模式:提供一个创建一系列或相互依赖对象的接口,而无须指定它们具体的类。
(3)生成器模式:将一个复杂对象的创建与它的表示分离,使得同样的创建过程可以创建不同的表示。
(4)原型模式:将原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
(5)单件模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
行为型
(1)责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
(2)命令模式:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
(3)解释器模式:给定一个语言,定义它文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
(4)迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
(5)中介者模式:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
(6)备忘录模式:在不破坏封装性的情况下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。
(7)观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
(8)状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
(9)策略模式:定义一系列算法,把它们一个个封装起来,并且可使它们可以相互替换。策略模式使算法可独立于使用它的客户而变化。
(10)模板方法模式:定义一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使子类可以不改变一个算法的结构即可定义该算法的某些特定步骤。
(11)访问者模式:表示一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下定义作用于这些元素的新操作。
结构型
(1)适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使原本由于接口不兼容而不能一起工作的那些类可以一起工作。
(2)组合模式:将对象组合成数形结构以表示”部分-整体“的层次结构。Composite使用户对单个对象和组合对象的使用具有一致性。
(3)代理模式:为其他对象提供一种代理以控制对这个对象的访问。
(4)享元模式:运用共享技术有效地支持大量细粒度的对象。
(5)外观模式:为系统的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使这一子系统更加容易使用。
(6)桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
(7)装饰模式:动态地给对象添加一些额外的职责,就功能来说装饰模式相比生成子类更为灵活。