编程

当前位置:时时彩平台 > 编程 > 设计模式:(四)行为型模式

设计模式:(四)行为型模式

来源:http://www.mrmtshipyard.com 作者:时时彩平台 时间:2019-10-06 08:00

图片 1观察者模式.png图片 2观察者模式通用类图

3、抽象工厂

图片 3

image

● AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
● ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
● AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
● ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

在抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或者具体类。具体工厂实现了抽象工厂,每一个具体的工厂方法可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族。

2、工厂方法

图片 4

image

● Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
● ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
● Factory(抽象工厂):在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
● ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。

与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类或者具体类。在抽象工厂中声明了工厂方法但并未实现工厂方法,具体产品对象的创建由其子类负责,客户端针对抽象工厂编程,可在运行时再指定具体工厂类,具体工厂类实现了工厂方法,不同的具体工厂可以创建不同的具体产品。


  • TerminalExpression——终结符表达式实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在栈中产生了一个VarExpression对象。
  • NonterminalExpression——非终结符表达式文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
  • Context——环境角色
7、适配器:不兼容结构的协调

图片 5

adapter.jpg

● Target(目标抽象类):目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。
● Adapter(适配器类):适配器可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。
● Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码。


//抽象处理者public abstract class Handler { private Handler nextHandler; //每个处理者都必须对请求做出处理 public final Response handleMessage(Request request){ Response response = null; //判断是否是自己的处理级别 if(this.getHandlerLevel().equals(request.getRequestLevel{ response = this.echo; }else{ //不属于自己的处理级别 //判断是否有下一个处理者 if(this.nextHandler != null){ response = this.nextHandler.handleMessage; }else{ //没有适当的处理者,业务自行处理 } } return response; } //设置下一个处理者是谁 public void setNext(Handler handler){ this.nextHandler = handler; } //每个处理者都有一个处理级别 protected abstract Level getHandlerLevel(); //每个处理者都必须实现处理任务 protected abstract Response echo(Request request);}//具体处理者public class ConcreteHandler1 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; }}public class ConcreteHandler2 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; }}public class ConcreteHandler3 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; }}//场景类public class Client { public static void main(String[] args) { //声明所有的处理节点 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); //设置链中的阶段顺序1-->2-->3 handler1.setNext; handler2.setNext; //提交请求,返回结果 Response response = handler1.handlerMessage(new Request; }}
5、原型模式:对象的克隆

图片 6

prototype.png

原型模式作为一种快速创建大量相同或相似对象的方式,在软件开发中应用较为广泛,很多软件提供的复制(Ctrl

  • C)和粘贴(Ctrl + V)操作就是原型模式的典型应用。

图片 7状态模式.png图片 8状态模式通用类图.png

21、状态:处理对象的多种状态及相互转换

图片 9

state.jpg

● Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同,因此将状态独立出去形成单独的状态类。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。
● State(抽象状态类):它用于定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各种不同状态对应的方法,而在其子类中实现类这些方法,由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中。
● ConcreteState(具体状态类):它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。

在状态模式中,我们将对象在不同状态下的行为封装到不同的状态类中,为了让系统具有更好的灵活性和可扩展性,同时对各状态下的共有行为进行封装,我们需要对状态进行抽象,引入了抽象状态类角色。


环境角色有两个不成文的约束:

1、简单工厂

图片 10

image

● Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product。
● Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
● ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用new关键字来创建对象,它是工厂模式家族中最简单的一员。
在使用简单工厂模式时,首先需要对产品类进行重构,不能设计一个包罗万象的产品类,而需根据实际情况设计一个产品层次结构,将所有产品类公共的代码移至抽象产品类,并在抽象产品类中声明一些抽象方法,以供不同的具体产品类来实现。


  • 基本方法基本方法也叫做基本操作,是由子类实现的方法,并且在模板方法被调用。

  • 模板方法可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。

24、访问者:操作复杂对象的结构

图片 11

visitor.gif

●Vistor(抽象访问者):抽象访问者为对象结构中每一个具体元素类ConcreteElement声明一个访问操作,从这个操作的名称或参数类型可以清楚知道需要访问的具体元素的类型,具体访问者需要实现这些操作方法,定义对这些元素的访问操作。
●ConcreteVisitor(具体访问者):具体访问者实现了每个由抽象访问者声明的操作,每一个操作用于访问对象结构中一种类型的元素。
●Element(抽象元素):抽象元素一般是抽象类或者接口,它定义一个accept()方法,该方法通常以一个抽象访问者作为参数。【稍后将介绍为什么要这样设计。】
●ConcreteElement(具体元素):具体元素实现了accept()方法,在accept()方法中调用访问者的访问方法以便完成对一个元素的操作。
● ObjectStructure(对象结构):对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。它可以结合组合模式来实现,也可以是一个简单的集合对象,如一个List对象或一个Set对象。

访问者模式中对象结构存储了不同类型的元素对象,以供不同访问者访问。访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同访问方式访问。在访问者模式中,增加新的访问者无须修改原有系统,系统具有较好的可扩展性。

在访问者模式中,抽象访问者定义了访问元素对象的方法,通常为每一种类型的元素对象都提供一个访问方法,而具体访问者可以实现这些访问方法。这些访问方法的命名一般有两种方式:一种是直接在方法名中标明待访问元素对象的具体类型,如visitElementA(ElementA elementA),还有一种是统一取名为visit(),通过参数类型的不同来定义一系列重载的visit()方法。当然,如果所有的访问者对某一类型的元素的访问操作都相同,则可以将操作代码移到抽象访问者类中。

//抽象的策略角色public interface Strategy { //策略模式的运算法则 public void doSomething();}//具体策略也是非常普通的一个实现类,只要实现接口中的方法就可以public class ConcreteStrategy1 implements Strategy { public void doSomething() { System.out.println("具体策略1的运算法则"); }}public class ConcreteStrategy2 implements Strategy { public void doSomething() { System.out.println("具体策略2的运算法则"); }}//封装角色public class Context { //抽象策略 private Strategy strategy = null; //构造函数设置具体策略 public Context(Strategy _strategy){ this.strategy = _strategy; } //封装后的策略方法 public void doAnythinig(){ this.strategy.doSomething(); }}//高层模块public class Client { public static void main(String[] args) { //声明一个具体的策略 Strategy strategy = new ConcreteStrategy1(); //声明上下文对象 Context context = new Context; //执行封装后的方法 context.doAnythinig(); }}

《设计模式Java版》 配套源码

模板方法模式确实非常简单,仅仅使用了Java的继承机制,但它是一个应用非常广泛的模式。其中,AbstractClass叫做抽象模板,它的方法分为两类:

也可以看看TutorialsPoint上的Design Patterns in Java Tutorial

图片 12行为型模式.png图片 13策略模式.png图片 14策略模式通用类图.png

18、中介者:协调多个对象之间的交互

图片 15

mediator.jpg

● Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
● ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
● Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
● ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法

中介者模式的核心在于中介者类的引入,在中介者模式中,中介者类承担了两方面的职责:

(1) 中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,可通过中介者来实现间接调用。该中转作用属于中介者在结构上的支持。

(2) 协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致的和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持

被观察者的职责非常简单,就是定义谁能够观察,谁不能观察,程序中使用ArrayList和Vector没有太大的差别,ArrayList是线程异步,不安全;Vector是线程同步,安全——就这点区别。

10、装饰者:扩展系统功能

图片 16

decorator.png

● Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。
● ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
● Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
● ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。

由于具体构件类和装饰类都实现了相同的抽象构件接口,因此装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。


上一篇:设计模式:结构性模式下一篇:设计模式:相似模式比较

20、观察者:对象间的联动

图片 17

observer.jpg

● Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。
● ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
● Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。
● ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。

观察者模式描述了如何建立对象与对象之间的依赖关系,以及如何构造满足这种需求的系统。观察者模式包含观察目标和观察者两类对象,一个目标可以有任意数目的与之相依赖的观察者,一旦观察目标的状态发生改变,所有的观察者都将得到通知。作为对这个通知的响应,每个观察者都将监视观察目标的状态以使其状态与目标状态同步,这种交互也称为发布-订阅(Publish-Subscribe)。观察目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅它并接收通知。


图片 18模板方法模式.png图片 19模板方法模式.png

17、迭代器:遍历聚合对象中的元素

图片 20

iterator.jpeg

● Iterator(抽象迭代器):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法,例如:用于获取第一个元素的first()方法,用于访问下一个元素的next()方法,用于判断是否还有下一个元素的hasNext()方法,用于获取当前元素的currentItem()方法等,在具体迭代器中将实现这些方法。
● ConcreteIterator(具体迭代器):它实现了抽象迭代器接口,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数。
● Aggregate(抽象聚合类):它用于存储和管理元素对象,声明一个createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色。
● ConcreteAggregate(具体聚合类):它实现了在抽象聚合类中声明的createIterator()方法,该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。

在迭代器模式中,提供了一个外部的迭代器来对聚合对象进行访问和遍历,迭代器定义了一个访问该聚合元素的接口,并且可以跟踪当前遍历的元素,了解哪些元素已经遍历过而哪些没有。迭代器的引入,将使得对一个复杂聚合对象的操作变得简单


  • Iterator抽象迭代器抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的3个方法:first()获得第一个元素,next()访问下一个元素,isDone()是否已经访问到底部(Java叫做hasNext。

  • ConcreteIterator具体迭代器具体迭代器角色要实现迭代器接口,完成容器元素的遍历。

  • Aggregate抽象容器容器角色负责提供创建具体迭代器角色的接口,必然提供一个类似createIterator()这样的方法,在Java中一般是iterator()方法。

  • Concrete Aggregate具体容器具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。

8、桥接模式:处理多维度变化

图片 21

bridge.png

●Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
●RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。
●Implementor(实现类接口):定义实现类的接口,这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系。
●ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法。

桥接模式是一个非常有用的模式,在桥接模式中体现了很多面向对象设计原则的思想,包括“单一职责原则”、“开闭原则”、“合成复用原则”、“里氏代换原则”、“依赖倒转原则”等。熟悉桥接模式有助于我们深入理解这些设计原则,也有助于我们形成正确的设计思想和培养良好的设计风格。

在使用桥接模式时,我们首先应该识别出一个类所具有的两个独立变化的维度,将它们设计为两个独立的继承等级结构,为两个维度都提供抽象层,并建立抽象耦合。通常情况下,我们将具有两个独立变化维度的类的一些普通业务方法和与之关系最密切的维度设计为“抽象类”层次结构(抽象部分),而将另一个维度设计为“实现类”层次结构(实现部分)。例如:对于毛笔而言,由于型号是其固有的维度,因此可以设计一个抽象的毛笔类,在该类中声明并部分实现毛笔的业务方法,而将各种型号的毛笔作为其子类;颜色是毛笔的另一个维度,由于它与毛笔之间存在一种“设置”的关系,因此我们可以提供一个抽象的颜色接口,而将具体的颜色作为实现该接口的子类。在此,型号可认为是毛笔的抽象部分,而颜色是毛笔的实现部分。

图片 22

pencil_bridge.png


9、组合:树形结构的处理

图片 23

composite.jpg

● Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
● Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
● Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。

如果不使用组合模式,客户端代码将过多地依赖于容器对象复杂的内部实现结构,容器对象内部实现结构的变化将引起客户代码的频繁变化,带来了代码维护复杂、可扩展性差等弊端。组合模式的引入将在一定程度上解决这些问题。


11、外观

图片 24

facade.jpg

● Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。
● SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已


  • Subject被观察者定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。

  • Observer观察者观察者接收到消息后,即进行update操作,对接收到的信息进行处理。

  • ConcreteSubject具体的被观察者定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

  • ConcreteObserver具体的观察者每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。

6、建造者:复杂对象的组装与创建

图片 25

builder.png

● Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
●ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
●Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
● Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。

在建造者模式的定义中提到了复杂对象,那么什么是复杂对象?简单来说,复杂对象是指那些包含多个成员属性的对象,这些成员属性也称为部件或零件,如汽车包括方向盘、发动机、轮胎等部件,电子邮件包括发件人、收件人、主题、内容、附件等部件。

在抽象类Builder中声明了一系列抽象的buildPartX()方法用于创建复杂产品的各个部件,具体建造过程在ConcreteBuilder中实现,此外还提供了工厂方法getResult(),用于返回一个建造好的完整产品。
在ConcreteBuilder中实现了buildPartX()方法,通过调用Product的setPartX()方法可以给产品对象的成员属性设值。不同的具体建造者在实现buildPartX()方法时将有所区别,如setPartX()方法的参数可能不一样,在有些具体建造者类中某些setPartX()方法无须实现(提供一个空实现)。而这些对于客户端来说都无须关心,客户端只需知道具体建造者类型即可。

在建造者模式的结构中还引入了一个指挥者类Director,该类主要有两个作用:一方面它隔离了客户与创建过程;另一方面它控制产品的创建过程,包括某个buildPartX()方法是否被调用以及多个buildPartX()方法调用的先后次序等。指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,即可通过指挥者类调用建造者的相关方法,返回一个完整的产品对象。在实际生活中也存在类似指挥者一样的角色,如一个客户去购买电脑,电脑销售人员相当于指挥者,只要客户确定电脑的类型,电脑销售人员可以通知电脑组装人员给客户组装一台电脑。


图片 26责任链模式通用类图.png

12、享元:实现对象的复用

图片 27

flyweight.jpg

● Flyweight(抽象享元类):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)。
● ConcreteFlyweight(具体享元类):它实现了抽象享元类,其实例称为享元对象;在具体享元类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。
● UnsharedConcreteFlyweight(非共享具体享元类):并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。
● FlyweightFactory(享元工厂类):享元工厂类用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中,享元池一般设计为一个存储“键值对”的集合(也可以是其他类型的集合),可以结合工厂模式进行设计;当用户请求一个具体享元对象时,享元工厂提供一个存储在享元池中已创建的实例或者创建一个新的实例(如果不存在的话),返回新创建的实例并将其存储在享元池中。

在享元模式中引入了享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,当用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象


13、代理

图片 28

proxy.jpg

● Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。
● Proxy(代理主题角色):它包含了对真实主题的引用,从而可以在任何时候操作真实主题对象;在代理主题角色中提供一个与真实主题角色相同的接口,以便在任何时候都可以替代真实主题;代理主题角色还可以控制对真实主题的使用,负责在需要的时候创建和删除真实主题对象,并对真实主题对象的使用加以约束。通常,在代理主题角色中,客户端在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实主题对象中的操作。
● RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。


抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限。


  • Receiver接收者角色该角色就是干活的角色,命令传递到这里是应该被执行的。
  • Command命令角色需要执行的所有命令都在这里声明。
  • Invoker调用者角色接收到命令,并执行命令
22、策略:算法的封装与切换

图片 29

strategy.jpg

● Context(环境类):环境类是使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
● Strategy(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。
● ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列具体策略类里面,作为抽象策略类的子类。在策略模式中,对环境类和抽象策略类的理解非常重要,环境类是需要使用算法的类。在一个系统中可以存在多个环境类,它们可能需要重用一些相同的算法。


在类图中还有一个角色:具体模板。ConcreteClass1和ConcreteClass2属于具体模板,实现父类所定义的一个或多个抽象方法,也就是父类定义的基本方法在子类中得以实现。

这里是对《设计模式Java版》的提炼汇总,在真正深入理解之前,方便速查。

4、单例

图片 30

singleton.png

● Singleton(单例):在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。


//抽象表达式public abstract class Expression { //每个表达式必须有一个解析任务 public abstract Object interpreter(Context ctx);}//终结符表达式public class TerminalExpression extends Expression { //通常终结符表达式只有一个,但是有多个对象 public Object interpreter(Context ctx) { return null; }}// 非终结符表达式public class NonterminalExpression extends Expression { //每个非终结符表达式都会对其他表达式产生依赖 public NonterminalExpression(Expression... expression){ } public Object interpreter(Context ctx) { //进行文法处理 return null; }}//客户类public class Client { public static void main(String[] args) { Context ctx = new Context(); //通常定一个语法容器,容纳一个具体的表达式,通常为ListArray、LinkedList、Stack等类型 Stack&Expression> stack = null; for{ //进行语法判断,并产生递归调用 } //产生一个完整的语法树,由各个具体的语法分析进行解析 Expression exp = stack.pop(); //具体元素进入场景 exp.interpreter; }}
14、职责链:请求的链式处理

图片 31

chain_of_responsibility.png

● Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。
● ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。

在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。


MyDemo
Github Demo

15、命令

图片 32

command.jpg

● Command(抽象命令类):抽象命令类一般是一个抽象类或接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接收者的相关操作。
● ConcreteCommand(具体命令类):具体命令类是抽象命令类的子类,实现了在抽象命令类中声明的方法,它对应具体的接收者对象,将接收者对象的动作绑定其中。在实现execute()方法时,将调用接收者对象的相关操作(Action)。
● Invoker(调用者):调用者即请求发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系。在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的execute()方法,从而实现间接调用请求接收者的相关操作。
● Receiver(接收者):接收者执行与请求相关的操作,它具体实现对请求的业务处理。

命令模式的本质是对请求进行封装,一个请求对应于一个命令,将发出命令的责任和执行命令的责任分割开。每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行相应的操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求如何被接收、操作是否被执行、何时被执行,以及是怎么被执行的。

命令模式的关键在于引入了抽象命令类,请求发送者针对抽象命令类编程,只有实现了抽象命令类的具体命令才与请求接收者相关联。在最简单的抽象命令类中只包含了一个抽象的execute()方法,每个具体命令类将一个Receiver类型的对象作为一个实例变量进行存储,从而具体指定一个请求的接收者,不同的具体命令类提供了execute()方法的不同实现,并调用不同接收者的请求处理方法。


23、模板方法

图片 33

template.jpg

● AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
● ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。


  • State——抽象状态角色接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
  • ConcreteState——具体状态角色每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
  • Context——环境角色定义客户端需要的接口,并且负责具体状态的切换。
19、备忘录:撤销功能的实现

图片 34

menonto.jpg

● Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
●Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。
●Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。

理解备忘录模式,关键在于如何设计备忘录类和负责人类。由于在备忘录中存储的是原发器的中间状态,因此需要防止原发器以外的其他对象访问备忘录,特别是不允许其他对象来修改备忘录。


图片 35迭代器模式通用类图.png

16、解释器:自定义语言的实现

图片 36

interpreter.jpg

● AbstractExpression(抽象表达式):在抽象表达式中声明了抽象的解释操作,它是所有终结符表达式和非终结符表达式的公共父类。
● TerminalExpression(终结符表达式):终结符表达式是抽象表达式的子类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例。通常在一个解释器模式中只有少数几个终结符表达式类,它们的实例可以通过非终结符表达式组成较为复杂的句子。
● NonterminalExpression(非终结符表达式):非终结符表达式也是抽象表达式的子类,它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此其解释操作一般通过递归的方式来完成。
● Context(环境类):环境类又称为上下文类,它用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。

在解释器模式中,每一种终结符和非终结符都有一个具体类与之对应,正因为使用类来表示每一条文法规则,所以系统将具有较好的灵活性和可扩展性。对于所有的终结符和非终结符,我们首先需要抽象出一个公共父类,即抽象表达式类。


责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果。

//通用抽象中介者public abstract class Mediator { //定义同事类 protected ConcreteColleague1 c1; protected ConcreteColleague2 c2; //通过getter/setter方法把同事类注入进来 public ConcreteColleague1 getC1() { return c1; } public void setC1(ConcreteColleague1 c1) { this.c1 = c1; } public ConcreteColleague2 getC2() { return c2; } public void setC2(ConcreteColleague2 c2) { this.c2 = c2; } //中介者模式的业务逻辑 public abstract void doSomething1(); public abstract void doSomething2();}// 通用中介者public class ConcreteMediator extends Mediator { @Override public void doSomething1() { //调用同事类的方法,只要是public方法都可以调用 super.c1.selfMethod1(); super.c2.selfMethod2(); } public void doSomething2() { super.c1.selfMethod1(); super.c2.selfMethod2(); }}// 抽象同事类public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator _mediator){ this.mediator = _mediator; }}// 具体同事类public class ConcreteColleague1 extends Colleague { //通过构造函数传递中介者 public ConcreteColleague1(Mediator _mediator){ super(_mediator); } //自有方法 self-method public void selfMethod1(){ //处理自己的业务逻辑 } //依赖方法 dep-method public void depMethod1(){ //处理自己的业务逻辑 //自己不能处理的业务逻辑,委托给中介者处理 super.mediator.doSomething1(); }}public class ConcreteColleague2 extends Colleague { //通过构造函数传递中介者 public ConcreteColleague2(Mediator _mediator){ super(_mediator); } //自有方法 self-method public void selfMethod2(){ //处理自己的业务逻辑 } //依赖方法 dep-method public void depMethod2“(){ //处理自己的业务逻辑 //自己不能处理的业务逻辑,委托给中介者处理 super.mediator.doSomething2(); }}
  • 把状态对象声明为静态常量,有几个状态对象就声明几个静态常量。
  • 环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。

图片 37备忘录模式.png图片 38备忘录模式通用类图.png

//抽象模板类public abstract class AbstractClass { //基本方法 protected abstract void doSomething(); //基本方法 protected abstract void doAnything(); //模板方法 public void templateMethod(){ /* * 调用基本方法,完成相关的逻辑 */ this.doAnything(); this.doSomething(); }}// 具体模板类public class ConcreteClass1 extends AbstractClass { //实现基本方法 protected void doAnything() { //业务逻辑处理 } protected void doSomething() { //业务逻辑处理 }}public class ConcreteClass2 extends AbstractClass { //实现基本方法 protected void doAnything() { //业务逻辑处理 } protected void doSomething() { //业务逻辑处理 }}//场景类public class Client { public static void main(String[] args) { AbstractClass class1 = new ConcreteClass1(); AbstractClass class2 = new ConcreteClass2(); //调用模板方法 class1.templateMethod(); class2.templateMethod(); }}
// 被观察者public abstract class Subject { //定义一个观察者数组 private Vector<Observer> obsVector = new Vector<Observer>(); //增加一个观察者 public void addObserver(Observer o){ this.obsVector.add; } //删除一个观察者 public void delObserver(Observer o){ this.obsVector.remove; } //通知所有观察者 public void notifyObservers(){ for(Observer o:this.obsVector){ o.update(); } }} //具体被观察者public class ConcreteSubject extends Subject { //具体的业务 public void doSomething(){ /* * do something */ super.notifyObservers(); }}//观察者public interface Observer { //更新方法 public void update();}//具体观察者public class ConcreteObserver implements Observer { //实现更新方法 public void update() { System.out.println("接收到信息,并进行处理!"); }}//场景类public class Client { public static void main(String[] args) { //创建一个被观察者 ConcreteSubject subject = new ConcreteSubject(); //定义一个观察者 Observer obs= new ConcreteObserver(); //观察者观察被观察者 subject.addObserver; //观察者开始活动了 subject.doSomething(); }}
//抽象迭代器public interface Iterator { //遍历到下一个元素 public Object next(); //是否已经遍历到尾部 public boolean hasNext(); //删除当前指向的元素 public boolean remove();}//具体迭代器public class ConcreteIterator implements Iterator { private Vector vector = new Vector(); //定义当前游标 public int cursor = 0; @SuppressWarnings("unchecked") public ConcreteIterator(Vector _vector){ this.vector = _vector; } //判断是否到达尾部 public boolean hasNext() { if(this.cursor == this.vector.size{ return false; }else{ return true; } } //返回下一个元素 public Object next() { Object result = null; if(this.hasNext{ result = this.vector.get(this.cursor++); }else{ result = null; } return result; } //删除当前元素 public boolean remove() { this.vector.remove(this.cursor); return true; }}//抽象容器public interface Aggregate { //是容器必然有元素的增加 public void add(Object object); //减少元素 public void remove(Object object); //由迭代器来遍历所有的元素 public Iterator iterator();}//具体容器public class ConcreteAggregate implements Aggregate { //容纳对象的容器 private Vector vector = new Vector(); //增加一个元素 public void add(Object object) { this.vector.add; } //返回迭代器对象 public Iterator iterator() { return new ConcreteIterator(this.vector); } //删除一个元素 public void remove(Object object) { this.remove; }}//场景类public class Client { public static void main(String[] args) { //声明出容器 Aggregate agg = new ConcreteAggregate(); //产生对象数据放进去 agg.add; agg.add; agg.add; //遍历一下 Iterator iterator = agg.iterator(); while(iterator.hasNext{ System.out.println(iterator.next; } }}

图片 39中介者模式.png图片 40中介者模式通用类图.png

//通用Receiver类public abstract class Receiver { //抽象接收者,定义每个接收者都必须完成的业务 public abstract void doSomething();}//具体的Receiver类public class ConcreteReciver1 extends Receiver{ //每个接收者都必须处理一定的业务逻辑 public void doSomething(){ }}public class ConcreteReciver2 extends Receiver{ //每个接收者都必须处理一定的业务逻辑 public void doSomething(){ }}//抽象的Command类public abstract class Command { //每个命令类都必须有一个执行命令的方法 public abstract void execute();}//具体的Command类public class ConcreteCommand1 extends Command { //对哪个Receiver类进行命令处理 private Receiver receiver; //构造函数传递接收者 public ConcreteCommand1(Receiver receiver){ this.receiver = receiver; } //必须实现一个命令 public void execute() { //业务处理 this.receiver.doSomething(); }}public class ConcreteCommand2 extends Command { //哪个Receiver类进行命令处理 private Receiver receiver; //构造函数传递接收者 public ConcreteCommand2(Receiver receiver){ this.receiver = receiver; } //必须实现一个命令 public void execute() { //业务处理 this.receiver.doSomething(); }}//调用者Invoker类public class Invoker { private Command command; //受气包,接受命令 public void setCommand(Command command){ this.command = command; } //执行命令 public void action(){ this.command.execute(); }}//场景类public class Client { public static void main(String[] args) { //首先声明调用者Invoker Invoker invoker = new Invoker(); //定义接收者 Receiver receiver = new ConcreteReciver1(); //定义一个发送给接收者的命令 Command command = new ConcreteCommand1; //把命令交给调用者去执行 invoker.setCommand; invoker.action(); }}

迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容器,例如Collection集合类型、Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的

  • Visitor——抽象访问者抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的。
  • ConcreteVisitor——具体访问者它影响访问者访问到一个类后该怎么干,要做什么事情。
  • Element——抽象元素接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。
  • ConcreteElement——具体元素实现accept方法,通常是visitor.visit,基本上都形成了一种模式了。
  • ObjectStruture——结构对象“元素产生者,一般容纳在多个不同类、不同接口的容器,如List、Set、Map等,在项目中,一般很少抽象出这个角色。
  • Context封装角色它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

  • Strategy抽象策略角色策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。,类图中的AlgorithmInterface是什么意思,algorithm是“运算法则”的意思,结合起来意思就明白了。

  • ConcreteStrategy具体策略角色实现抽象策略中的操作,该类含有具体的算法。

图片 41责任链模式.png

图片 42命令模式.png图片 43命令模式通用类图.png

策略模式的重点就是封装角色,它是借用了代理模式的思路,大家可以想想,它和代理模式有什么差别,差别就是策略模式的封装角色和被封装的策略类不用是同一个接口,如果是同一个接口那就成为了代理模式。

//抽象元素public abstract class Element { //定义业务逻辑 public abstract void doSomething(); //允许谁来访问 public abstract void accept(IVisitor visitor);}//具体元素public class ConcreteElement1 extends Element{ //完善业务逻辑 public void doSomething(){ //业务处理 } //允许那个访问者访问 public void accept(IVisitor visitor){ visitor.visit; }}public class ConcreteElement2 extends Element{ //完善业务逻辑 public void doSomething(){ //业务处理 } //允许那个访问者访问 public void accept(IVisitor visitor){ visitor.visit; }}//抽象访问者public interface IVisitor { //可以访问哪些对象 public void visit(ConcreteElement1 el1); public void visit(ConcreteElement2 el2);}//具体访问者public class Visitor implements IVisitor { //访问el1元素 public void visit(ConcreteElement1 el1) { el1.doSomething(); } //访问el2元素 public void visit(ConcreteElement2 el2) { el2.doSomething(); }}// 结构对象public class ObjectStruture { //对象生成器,这里通过一个工厂方法模式模拟 public static Element createElement(){ Random rand = new Random(); if(rand.nextInt > 50){ return new ConcreteElement1(); }else{ return new ConcreteElement2(); } }}// 场景类public class Client { public static void main(String[] args) { for(int i=0;i<10;i++){ //获得元素对象 Element el = ObjectStruture.createElement(); //接受访问者访问 el.accept(new Visitor; } }}

图片 44解释器模式.png图片 45解释器模式通用类图.png

为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写。

  • Mediator 抽象中介者角色抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
  • Concrete Mediator 具体中介者角色具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
  • Colleague 同事角色每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作
//抽象状态角色public abstract class State { //定义一个环境角色,提供子类访问 protected Context context; //设置环境角色 public void setContext(Context _context){ this.context = _context; } //行为1 public abstract void handle1(); //行为2 public abstract void handle2();}//状态角色public class ConcreteState1 extends State { @Override public void handle1() { //本状态下必须处理的逻辑 } @Override public void handle2() { //设置当前状态为stat2 super.context.setCurrentState(Context.STATE2); //过渡到state2状态,由Context实现 super.context.handle2(); }}public class ConcreteState2 extends State { @Override public void handle1() { //设置当前状态为state1 super.context.setCurrentState(Context.STATE1); //过渡到state1状态,由Context实现 super.context.handle1(); } @Override public void handle2() { //本状态下必须处理的逻辑 }}//具体环境角色public class Context { //定义状态 public final static State STATE1 = new ConcreteState1(); public final static State STATE2 = new ConcreteState2(); //当前状态 private State CurrentState; //获得当前状态 public State getCurrentState() { return CurrentState; } //设置当前状态 public void setCurrentState(State currentState) { this.CurrentState = currentState; //切换状态 this.CurrentState.setContext; } //行为委托 public void handle1(){ this.CurrentState.handle1(); } public void handle2(){ this.CurrentState.handle2(); }}

图片 46迭代模式.png

策略模式使用的就是面向对象的继承和多态机制,非常容易理解和掌握,策略模式的三个角色:

//发起人角色public class Originator { //内部状态 private String state = ""; public String getState() { return state; } public void setState(String state) { this.state = state; } //创建一个备忘录 public Memento createMemento(){ return new Memento(this.state); } //恢复一个备忘录 public void restoreMemento(Memento _memento){ this.setState(_memento.getState; }}//备忘录角色public class Memento { //发起人的内部状态 private String state = ""; //构造函数传递参数 public Memento(String _state){ this.state = _state; } public String getState() { return state; } public void setState(String state) { this.state = state; }}//备忘录管理员角色public class CareTaker { private List<Memento> mementoList = new ArrayList<Memento>(); public void add(Memento state){ mementoList.add; } public Memento get(int index){ return mementoList.get; }}//场景类public class Client { public static void main(String[] args) { Originator originator = new Originator(); CareTaker careTaker = new CareTaker(); originator.setState("State #1"); originator.setState("State #2"); careTaker.add(originator.saveStateToMemento; originator.setState("State #3"); careTaker.add(originator.saveStateToMemento; originator.setState("State #4"); System.out.println("Current State: " + originator.getState; originator.restoreMemento(careTaker.get; System.out.println("First saved State: " + originator.getState; originator.restoreMemento(careTaker.get; System.out.println("Second saved State: " + originator.getState; }}
  • Originator发起人角色记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
  • Memento备忘录角色负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
  • Caretaker备忘录管理员角色对备忘录进行管理、保存和提供备忘录。

图片 47访问者模式.png图片 48访问者模式通用类图.png

本文由时时彩平台发布于编程,转载请注明出处:设计模式:(四)行为型模式

关键词:

上一篇:单例模式

下一篇:没有了