第六次作业

行为型模式

一、Template Method模板

1.模式的定义与特点

模板方法(Template Method)模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。

该模式的主要优点如下。

1.它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。

2.它在父类中提取了公共的部分代码,便于代码复用。

3.部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

该模式的主要缺点如下。

 1.对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。

 2.父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

 3.由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。

2、动机

在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

 

3、意图

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

4、要点

• Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展

点,是代码复用方面的基本实现结构。

除了可以灵活应对子步骤的变化外,不要调用我,让我来调用你的反向控制结构是Template Method的典型应用。

在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。

二、Command(命令)模式

1、定义

命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

2、动机

在软件构建过程中,行为请求者行为实现者通常呈现一种紧耦合。但在某些场合——比如需要对行为进行记录、撤销/重做(undo/redo)、事等处理,这种无法抵御变化的紧耦合是不合适

的。

3、意图

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作

4、要点

• Command模式的根本目的在于将行为请求者行为实现者解耦,在面向对象语言中,常见的实现手段是将行 为抽象为对象

实现Command接口的具体命令对象ConcreteCommand有时候根据需要可能会保存一些额外的状态信息。

通过使用Composite模式,可以将多个命令封装为一个复合命令”MacroCommand

• Command模式与C#中的Delegate有些类似。但两者定义 行为接口的规范有所区别:Command以面向对象中的-实现来定义行为接口规范,更严格,更符合抽象原则;Delegate以函数签名来定义行为接口规范,更灵活, 但抽象能力比较弱。

三、Interpreter(解释器)模式

1、定义和特点

给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子

解释器的优点如下。

1.扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。

2.容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

解释器模式的主要缺点如下。

1.执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。

2.会引起类膨胀。

3.可应用的场景比较少。需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

2、动机

在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。

3、意图

给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。

4、要点

• Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足业务规则频繁变化,且类的模式不断重复出现,并且容易抽象为语法规则的问题才适合使用Interpreter模式。

使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地扩展文法。

• Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interperter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

四、Mediator(中介者)模式

1、定义和特点

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

中介者模式的优点如下。

1.类之间各司其职,符合迪米特法则。

2.降低了对象之间的耦合性,使得对象易于独立地被复用。

3.将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。

其主要缺点是:中介者模式将原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。

2、动机

在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。

3、意图

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

4、要点

将多个对象间复杂的关联关系解耦,Mediator式将多个对象间的控制逻辑进行集中管理,变个对象互相关联多个对象和一个中介者关,简化了系统的维护,抵御了可能的变化。

随着控制逻辑的复杂化,Mediator具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理。

• Façade模式是解耦系统外到系统内(单向)的对象关联关系;Mediator模式是解耦系统内各个对象之间(双向)的关联关系。

五、Iterator(迭代器)模式

1、定义和特点

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示,迭代器模式是一种对象行为型模式。

其主要优点如下。

1.访问一个聚合对象的内容而无须暴露它的内部表示。

2.遍历任务交由迭代器完成,这简化了聚合类。

3.它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。

4.增加新的聚合类和迭代器类都很方便,无须修改原有代码。

5.封装性良好,为遍历不同的聚合结构提供一个统一的接口。

其主要缺点是:增加了类的个数,这在一定程度上增加了系统的复杂性。

2、动机

集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种透明遍历也为同一种算法在多种集合对象上进行操作提供了可能。

3、意图

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

4、要点

• 迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。

• 迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。

• 迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。

六、Observer(观察者)模式

1、定义和特点

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式是一种对象行为型模式。

其主要优点如下。

1.降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。

2.目标与观察者之间建立了一套触发机制。

它的主要缺点如下。

1.目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。

2.当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

2、动机

使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

3、意图

定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新

4、要点

使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。

目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知,目标对象对此一无所知。

七、Chain of Responsibility(职责链)模式

1、定义

为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

注意:责任链模式也叫职责链模式。

2、动机

在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。

3、意图

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

4、要点

• Chain of Responsibility 模式的应用场合在于一个请求可能有多个接受者,但是最后真正接受者只有一个,只有这时候请求发送者与接受者的耦合才有可能出现变化脆弱的症职责链的目的就是将二者解耦,从而更好地应对变化。

应用了Chain of Responsibility 模式后,对象的职责分派将更具灵活性。我们可以在运行动态添加修改请求的处理职责。

如果请求传递到职责链的末尾仍得不到处理,应该有一个

合理的缺省机制。这也是每一个接受对象的责任,而不是

发出请求的对象的责任

八、Memento(备忘录)模式

1、定义和特点

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

其主要优点如下。

 1.提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。

 2.实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。

 3.简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

其主要缺点是:资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

2、动机

如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性。

3、意图

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。

4、要点

备忘录(Memento)存储原发器(Originator)对 象的内部状态,在需要时恢复原发器状态。Memento模式适用于由原发器管理,却又必须存储在原发器之外的信息

在实现Memento模式中,要防止原发器以外的对象访问备忘录对象。备忘录对象有两个接口,一个为原发器使用的宽接口;一个为其他对象使用的窄接口。

在实现Memento模式时,要考虑拷贝对象状态的效率问题,如果对象开销比较大,可以采用某种 增量式改变来改进Memento模式。

九、State(状态)模式

1、定义

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

2、动机

如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合? 

3、意图

允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

4、要点

State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。

• 为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。

• 如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。

十、Visitor(访问者)模式。

1、定义

将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

2、动机

如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?

3、意图

表示一个作用于某对象结构中的各元素的操作。它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。

4、要点

• Visitor模式通过所谓双重分发(double dispatch)来实现在不更改Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作。

所谓双重分发即 Visitor模式中间包括了两个多态分发(注意其中的多态机制):第一个为

accept 方法的多态辨析;第二个为visit方法的多态辨析。

• Visitor模式的最大缺点在于扩展类层次结构(增添新的Element子类),会导致Visitor类的改变。因此Vistor模式适用于“Element类层次结构稳定,而其中的操作却经常面临频繁改动

 

posted @ 2021-02-26 16:04  19A3  阅读(59)  评论(0编辑  收藏  举报