设计模式---行为型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Yue510/article/details/84135336

设计模式—行为型

行为型模式一共有11种:

  • 策略模式(Strategy)
  • 模板方法模式(Template Method)
  • 命令模式(Command)
  • 中介者模式(Mediator)
  • 观察者模式(Observer)
  • 迭代器模式(Iteratior)
  • 访问者模式(Visiter)
  • 职责链模式(Chain of Responsibility)
  • 备忘录模式(Memento)
  • 状态模式(State)
  • 解释器模式(Interpreter)
      其中有分为:
      算法封装:模板方法、策略、命令模式
      对象去耦:中介、观察者模式
      抽象集合:迭代器模式
      行为扩展:访问者、职责链模式
      对象状态:状态模式
      解释器模式

模板方法模式(Template Method)
1.定义:
定义一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使子类可以重定义算法的某些特定步骤而不改变该算法的结构。(定义一个模板结构,具体内容子类去实现)
2.作用:
提高代码复用性 ,将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。
实现了反向控制 ,通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 & 符合“开闭原则”。
3.结构图
在这里插入图片描述
4.优缺点
优点:
提高代码复用性 ,将相同部分的代码放在抽象的父类中。
提高了拓展性 ,将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为。
实现了反向控制 ,通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,实现了反向控制 & 符合“开闭原则”。
缺点:
引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。
5.应用场景
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复;
控制子类的扩展。

策略模式(Strategy)
1.定义:
它定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。(简单来说:准备一组算法 , 将每一个算法封装起来,让外部按需调用 ,使得互换)
2.作用
算法可独立于使用外部而变化;
客户端方便根据外部条件选择不同策略来解决不同问题。
3.结构图
角色:策略接口(Strategy)、具体策略、环境对象
在这里插入图片描述
4.优缺点
优点:
策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。
易于扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“。
避免使用多重条件选择语句(if else),充分体现面向对象设计思想。
缺点:
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。
5.应用场景
复杂的算法 / 数据结构
类的行为 / 方法

命令模式(Command)
1.定义
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
2.作用
主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。(消除庞大的条件分支语句)
3.结构图
角色:客户端(Client)、命令调用者(Invoker)、命令接口(Command)、具体命令(ConcreteCommand)、命令接收者(Receiver)
在这里插入图片描述
4.优缺点
优点
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
5.应用场景
系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
系统需要在不同的时间指定请求、将请求排队和执行请求。
系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
系统需要将一组操作组合在一起,即支持宏命令。

中介者模式(Mediator)
1.定义
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地互相吸引,从而使其耦合松散,而且可以独立地改变它们之间的交互。
2.作用
是用来降低多个对象和类之间的通信复杂性。
3.结构图
角色:中介者接口(Mediator)、具体中介者、同事者接口(Colleague),具体同事者。
在这里插入图片描述
4.优缺点
优点
降低了类的复杂度,将一对多转化成了一对一。
各个类之间的解耦。
符合迪米特原则。
缺点
中介者会庞大,变得复杂难以维护。
5.应用场景
一组定义良好的对象,现在要进行复杂的相互通信。
想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

观察者模式(Observer)又叫做发布-订阅(Publish/Subscribe)模式
1.定义
定义了一种一对多的依赖关系,如果你多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
2.作用
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
3.结构图
角色:发布者接口(Subject)、具体发布者、监听者接口(Observer)、具体监听者。
在这里插入图片描述
4.优缺点
优点
观察者和被观察者是抽象耦合的。
建立一套触发机制。
缺点
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
5.应用场景
一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

迭代器模式(Iteratior)
1.定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
2.作用
不同的方式来遍历整个整合对象。
3.结构图
角色:迭代器、集合
在这里插入图片描述
4.优缺点
优点
1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
5.应用场景
访问一个聚合对象的内容而无须暴露它的内部表示。
需要为聚合对象提供多种遍历方式。
为遍历不同的聚合结构提供一个统一的接口。
6. 注意事项:
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

访问者模式(Visiter)
1.定义
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
2.作用
稳定的数据结构和易变的操作耦合问题。
3.结构图
角色:访问者(Vistor)接口、具体访问者、访问元素(Element)接口、具体元素
在这里插入图片描述
4.优缺点
优点
符合单一职责原则;优秀的扩展性;灵活性。
缺点
具体元素对访问者公布细节,违反了迪米特原则。
具体元素变更比较困难。
违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
5.应用场景
对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
6.注意事项:
访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。

职责链模式(Chain of Responsibility)
1.定义
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之前的耦合关系。将这个对象连成一天链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2.作用
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
3.结构图
在这里插入图片描述
4.优缺点
优点
降低耦合度。它将请求的发送者和接收者解耦。
简化了对象。使得对象不需要知道链的结构。
增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
增加新的请求处理类很方便。
缺点
不能保证请求一定被接收。
系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
可能不容易观察运行时的特征,有碍于除错。
5.应用场景
有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可动态指定一组对象处理请求。

备忘录模式(Memento)
1.定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2.作用
所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
3.结构图
角色:有三个角色:发起人(Originatior)、备忘录(Memento)、看管人(Caretaker)。
在这里插入图片描述
4.优缺点
优点: 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。 2、实现了信息的封装,使得用户不需要关心状态的保存细节。
缺点:消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
5.应用场景: 1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。

状态模式(State)
1.定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
2.作用
对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
3.结构图
角色:环境(context)、状态(state)
在这里插入图片描述
4.优缺点
优点
1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点
1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。
5.应用场景
行为随状态改变而改变的场景。条件、分支语句的代替者。
6.注意事项:
在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

解释器模式(Interpreter)
1.定义
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
2.作用
对于一些固定文法构建一个解释句子的解释器。
3.结构图
角色:环境(context)、解释器
在这里插入图片描述
4.优缺点
优点
可扩展性比较好,灵活;增加了新的解释表达式的方式;易于实现简单文法。
缺点
可利用场景比较少;对于复杂的文法比较难维护;解释器模式会引起类膨胀;解释器模式采用递归调用方法。
5.应用场景
可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
一些重复出现的问题可以用一种简单的语言来进行表达。
一个简单语法需要解释的场景。

猜你喜欢

转载自blog.csdn.net/Yue510/article/details/84135336