设计模式之行为型模式

  行为型模式(11种)

这里写图片描述

 策略模式

特点:定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化
这里写图片描述
适用场景:
(1) 一个系统需要动态地在几种算法中选择一种,那么可以将这些算法封装到一个个的具体算法类中,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,根据“里氏代换原则”和面向对象的多态性,客户端可以选择使用任何一个具体算法类,并只需要维持一个数据类型是抽象算法类的对象。
(2) 一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句。
(3) 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性。

优点:
1,算法切换简单
2,避免多重条件判断
3,具有良好的扩展性

缺点:
1,客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2,策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类。
3,无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。

  模版方法模式

特点:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
这里写图片描述
适用场景:
(1) 对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。即:一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
(2) 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
(3) 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。
优点:
1,在父类中定义一个算法,由它的子类来实现细节的处理
2,模板方法是一种代码复用技术,可以将公共行为放在父类中
3,可以通过子类来覆盖父类的基本方法
缺点:
需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,会导致系统更加庞大,降低系统性能

 观察者模式

特点:定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新
这里写图片描述
适用场景:
(1) 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用。
(2) 一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变,也不知道这些对象是谁。
(3) 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象,可以使用观察者模式创建一种链式触发机制。
优点:
1,可以实现表示层和数据逻辑层的分离2,在观察目标和观察者之间建立一个抽象的耦合
3,支持广播通信4,增加新的具体观察者时,不需要修改原有系统代码
缺点:
1,如果一个观察目标对象有很多直接和间接观察者,将所有观察者都通知,会花费很多时间
2,如果观察者和观察目标之间存在循环依赖,会导致循环调用,从而导致系统崩溃

 迭代器模式

特点:提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示
这里写图片描述
使用场景:
(1) 访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时无须了解其内部实现细节。
(2) 需要为一个聚合对象提供多种遍历方式。
(3) 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。
优点:
1,支持以不同的方式遍历一个聚合对象
2,简化了聚合类
3,在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码
缺点:设计难度较大

职责链模式

特点:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
这里写图片描述
适用场景:
(1) 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。
(2) 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
(3) 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。
优点:
1,对象不需要知道是哪儿一个对象处理他的请求,只需要知道这个请求会被处理,从而降低了系统的耦合度
2,增加灵活性,可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的职责
3,在系统中增加一个新的具体请求处理者时,不需要修改原有系统的代码,只需要在客户端重新建链即可
缺点:
1,由于一个请求没有明确的接受者,这个请求不一定会被处理
2,对于比较长的职责链,可能涉及到多个处理对象,系统性能受到影响
3,如果职责链建立的不是太合理,可能会造成循环调用,使系统陷入死循环

 命令模式

特点:将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
这里写图片描述
适用场景:
(1) 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。请求调用者无须知道接收者的存在,也无须知道接收者是谁,接收者也无须关心何时被调用。
(2) 系统需要在不同的时间指定请求、将请求排队和执行请求。一个命令对象和请求的初始调用者可以有不同的生命期,换言之,最初的请求发出者可能已经不在了,而命令对象本身仍然是活动的,可以通过该命令对象去调用请求接收者,而无须关心请求调用者的存在性,可以通过请求日志文件等机制来具体实现。
(3) 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
(4) 系统需要将一组操作组合在一起形成宏命令。

优点:
1,降低耦合度。因为请求者和接收者之间不存在引用,因为请求者和接收者之间是完全解耦的
2,增加灵活性。由于增加新的具体命令类不会影响其他类,所以增加新的类时很容易
3,可以比较容易的设计一个命令队列
4,为请求的撤销和恢复操作提供了一种设计和实现方案
缺点:
可能会导致某些系统有过多的具体命令类。因为针对每一个请求接收者的调用操作都需要设计一个具体命令类

  备忘录模式

特点:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态
这里写图片描述
适用场景:
(1) 状态模式的使用必然会增加系统中类和对象的个数,导致系统运行开销增大。
(2) 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,增加系统设计的难度。
(3) 状态模式对“开闭原则”的支持并不太好,增加新的状态类需要修改那些负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
优点:
提供了一种状态恢复的机制
缺点:
资源消耗较大

  状态模式

特点:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
这里写图片描述
使用场景:
(1) 状态模式的使用必然会增加系统中类和对象的个数,导致系统运行开销增大。
(2) 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,增加系统设计的难度。
(3) 状态模式对“开闭原则”的支持并不太好,增加新的状态类需要修改那些负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
优点:
1,封装了状态的转换规则,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中
2,将所有与某个状态有关的行为放到一个类中
3,可以让多个环境对象共享一个状态对象
缺点:
1,状态模式使用,会导致系统运行开销增大
2,状态模式如果使用不当,会增加系统设计难度

  访问者模式

特点:提供一个作用于某对象结构中的各元素的操作表示,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作
这里写图片描述
适用场景:
(1) 一个对象结构包含多个类型的对象,希望对这些对象实施一些依赖其具体类型的操作。在访问者中针对每一种具体的类型都提供了一个访问操作,不同类型的对象可以有不同的访问操作。
(2) 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。访问者模式使得我们可以将相关的访问操作集中起来定义在访问者类中,对象结构可以被多个不同的访问者类所使用,将对象本身与对象的访问操作分离。
(3) 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
优点:
1,增加新的访问操作很方便
2,将有关元素对象的访问行为集中到一个访问者对象中,而不会分散在一个个的元素类中
缺点
1,增加新的类很困难
2,破坏封装

   中介者模式

特点:用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,是“迪米特法则”的一个典型应用
这里写图片描述
适用情景:
(1) 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
(2) 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
(3) 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。
优点:
1,简化了对象之间的交互,
缺点:
可能会导致中介者类非常复杂,使得系统难以维护

 解释器模式

特点:定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,其中“语言”是指使用规定格式和语法的代码
这里写图片描述
适用场景:
(1) 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
(2) 一些重复出现的问题可以用一种简单的语言来进行表达。
优点:
1,易于改变和扩展文法
2,每一条文法规则都可以表示为一个类,因此可以方便的实现一个简单的语言
3,增加新的解释表达式比较方便。如果用户需要增加新的解释表达式,只需要对应增加一个新的表达式即可,原有表达式类不需要做修改
缺点:
1,对于复杂文法难以维护。在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,会导致系统难以管理和维护
2,执行效率较低。由于在解释器模式中使用了大量的循环和递归调用,所以可能导致系统的执行效率变低

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值