设计模式应试复习篇(七)——举例说明11种行为型模式的适用情景

1、职责链模式

很多情况下,在一个软件系统中可以处理某个请求的对象不止一个,比如我们在学校提交请假的申请表,辅导员、系主任、院长和校长都可以处理申请表,他们可以构成一条处理申请表的链式结构,申请表沿着这条链进行传递,这条链就称为职责链。职责链可以是一条直线、一个环或者一个树形结构。 链上的每一个对象都是请求的处理者,职责链模式可以将请求的处理者组织成一条链,并让请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,实现请求发送者和请求处理者解耦。这就是职责链模式的模式动机。

职责链模式适用情况包括:有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定;在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;可动态指定一组对象处理请求。

2、命令模式(别名为动作(Action)模式或事务(Transaction)模式)

在现实生活中,通过开关可以控制一些电器的打开和关闭,例如电灯或者排气扇。在购买开关时,我们并不知道它将来到底用于控制什么电器,也就是说,开关与电灯、排气扇并无直接关系,一个开关在安装之后可能用来控制电灯,也可能用来控制排气扇或者其他电器设备。开关与电器之间通过电线建立连接,如果开关打开,则电线通电,电器工作;反之,开关关闭,电线断电,电器停止工作。相同的开关可以通过不同的电线来控制不同的电器。注意与外观模式区别开。

命令模式将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

3、解释器模式

假如要开发一套机器人控制程序,提供图形化的设置界面,用户通过对界面进行操作可以创建一个机器人控制指令,机器人在收到指令后将按照指令的设置进行移动,例如输入控制指令:up move 5,则“向上移动5个单位”;输入控制指令:down  run 10 and left move 20,则“向下快速移动10个单位再向左移动20个单位”。开发人员就要编写代码来解析控制指令的文法规则,并按指令要求来驱动机器人完成相应动作。

解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。

解释器模式适用情况包括:可以将一个需要解释执行的语言中的句子表示为一个抽象语法树;一些重复出现的问题可以用一种简单的语言来进行表达;文法较为简单且效率不是关键问题。

4、迭代器模式

在现实生活中,我们通过遥控器来操控电视机,进行开机、关机、换台、改变音量等操作,而无须直接操作电视机。 我们可以将电视机看成一个存储电视频道的集合对象,通过遥控器可以对电视机中的电视频道集合进行操作,如返回上一个频道、跳转到下一个频道或者跳转至指定的频道。在软件开发中,也存在大量类似电视机一样的类,它们可以存储多个成员对象(元素),这些类通常称为聚合类(Aggregate Classes),对应的对象称为聚合对象。比照电视机遥控器的功能角色,我们将遍历数据的行为从聚合对象中分离出来,封装在一个被称之为“迭代器”的对象中,由迭代器来提供遍历聚合对象内部数据的行为,这就是迭代器模式。

迭代器模式适用情况包括:访问一个聚合对象的内容而无须暴露它的内部表示;需要为聚合对象提供多种遍历方式;为遍历不同的聚合结构提供一个统一的接口。

5、中介者模式

在有些软件中,某些类/对象之间的相互调用关系错综复杂,类似QQ用户之间的关系,此时,我们特别需要一个类似“QQ群”一样的中间类来协调这些类/对象之间的复杂关系,以降低系统的耦合度。有一个设计模式正为此而诞生,它就是中介者模式。

就像QQ用户通过QQ群就可以同时接收到相同的消息,而不需要一个一个发送。

中介者模式的主要优点在于简化了对象之间的交互,将各同事解耦,还可以减少子类生成,对于复杂的对象之间的交互,通过引入中介者,可以简化各同事类的设计和实现;中介者模式主要缺点在于具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

6、备忘录模式(又叫做Token模式或快照模式)

备忘录模式是一种给我们的软件提供后悔药的机制,通过它可以使系统恢复到某一特定的历史状态。可以类比快捷键Ctrl+Z的作用。

备忘录模式适用情况包括:保存一个对象在某一个时刻的状态或部分状态,这样以后需要时它能够恢复到先前的状态;如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

7、观察者模式

考虑读者订阅报纸的情况,订阅者类向出版者类订阅报纸,很明显不会只有一个订阅者对象订阅报纸,订阅者对象可以有很多;当出版者对象出版新报纸的时候,多个订阅者对象如何知道呢?还有订阅者对象如何得到新报纸的内容呢? 进一步抽象描述这个问题:当一个对象的状态发生改变的时候,如何让依赖于它的所有对象得到通知,并进行相应的处理呢? 解决上述问题的一个合理的解决方案就是观察者模式!

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。

观察者模式适用情况包括:一个抽象模型有两个方面,其中一个方面依赖于另一个方面;一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变;一个对象必须通知其他对象,而并不知道这些对象是谁;需要在系统中创建一个触发链。

8、状态模式

很多事物都具有多种状态,而且在不同状态下会具有不同的行为,这些状态在特定条件下还将发生相互转换。就像水,它可以凝固成冰,也可以受热蒸发后变成水蒸汽,水可以流动,冰可以雕刻,蒸汽可以扩散。为了更好地对这些具有多种状态的对象进行设计,我们将学习用于描述对象状态及其转换的状态模式。

状态模式的主要优点在于封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为,还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;其缺点在于使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求。

9、策略模式

完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务,例如我们在外出旅游时可以选择多种不同的出行方式,如骑自行车、坐汽车、坐火车或者坐飞机。 在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。这就是策略模式的模式动机。

策略模式适用情况包括:在一个系统里面有许多类,它们之间的区别仅在于它们的行为,使用策略模式可以动态地让一个对象在许多行为中选择一种行为;一个系统需要动态地在几种算法中选择一种;避免使用难以维护的多重条件选择语句;希望在具体策略类中封装算法和与相关的数据结构。

10、模板方法模式

在软件开发中,有时某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点单”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。

模板方法模式适用情况包括:一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复;对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法,而一些可以改变的细节由其子类来实现;通过模板方法模式还可以控制子类的扩展。

11、访问者模式

观察上面处方单,一张处方单接受划价人员和药房工作人员的先后访问,划价人员和药房工作人员都在处方单上填了信息,但是信息代表的意思是两种不同的类型,而且不同的工作人员接触到处方单的方式也不一样。

对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生。

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

猜你喜欢

转载自blog.csdn.net/qq_40996041/article/details/83590211