行为型模式关注系统中对象之间的相互交互,研究系统在运行时对象之间的相互通信与协作,进一步明确对象的职责。行为型模式是GoF设计模式中最为庞大的一种模式,它包括11种设计模式。
今天就让我们一起来揭开行为型模式神秘的面纱。
一、职责链模式 Chain of Responsibility Pattern
1. 模式动机
职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需要将请求发送到链上即可,将请求的发送者和请求的处理者解耦。这就是职责链模式的模式模式动机。
2. 模式定义
避免请求发送者与接受者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式,又叫责任链模式,是一种对象行为型模式。
3. 模式结构
职责链包含如下角色:Handler抽象处理者、ConcreteHandler具体处理者、Client客户类
4. 模式分析
职责链模式的核心在于抽象处理者类的设计,在抽象处理者类种定义了一个自类型的对象,用于维持一个对处理者下家的引用,以便将请求传递给下家,抽象处理者的典型代码如下:
public abstract class Handler { protected Handler successor; public void setSuccessor(Handler successor) { this.successor = successor; } public abstract void handleRequest(String request); }
具体处理者是抽象处理者的子类,它具有两大作用:第一是处理请求,不同的具体处理者以不同的形式实现抽象请求处理方法handleRequest();第二是转发请求,如果该请求超出了当前处理者类的权限,可以将该请求转发给下家,这个工作也是通过具体处理者类来完成的。具体处理者类的典型代码如下:
public class Concretehandler extends Handler{ public void handlerRequest(String request){ if(请求request满足条件){ ... //处理请求 }else{ this.successor.handleRequest(request);//转发请求 } } }
5. 模式应用:过滤器链
6. 模式扩展
一个纯的职责链模式要求一个具体处理者对象只能在两个行为中选择一个:一个是承担责任,另一个是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又将责任向下传的情况。
在一个纯的职责链模式里,一个请求必须被某一个处理者对象接收;在一个不纯的职责链模式里面,一个请求可以最终不被任何接收端对象所接收。实际应用中,纯的职责链模式的例子比较少。
7. 主要优缺点
职责链模式的主要优点在于可以降低系统的耦合度,简化对象的相互连接,同时增强对象指派职责的灵活性,增加新的请求处理类也很方便;其主要缺点在于不能保证请求一定被接收,且对于比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。
二、命令模式 Command Pattern
1. 定义
将一个请求封装成一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作模式或事务模式。
2. 模式结构
角色:Command抽象命令类、ConcreteCommand具体命令类、Invoker调用者、Receiver接收者、Client客户类
3. 模式分析
4. 模式应用
5. 主要优缺点
命令模式的主要优点在于降低系统的耦合度,增加新的命令很方便,而且可以比较容易地设计出一个命令队列和宏命令,并方便地实现对请求的撤销和恢复;其主要缺点在于可能导致某些系统有过多的具体命令类。
三、解释器模式 Interpreter Pattern
1. 定义
定义语言的文法,并且建立一个解释器来解释该语言中的句子,这里的”语言“意思是使用规定格式和语法的代码,它是一种类行为模式。
2. 模式结构
四、迭代器模式 Iterator Pattern
1. 定义:提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名游标(Cursor)。迭代器模式是一种对象行为型模式。
2. 模式结构
Iterator抽象迭代器、ConcreteIterator具体迭代器、Aggregate抽象聚合类、ConcreteAggregate具体聚合类
3. 模式应用 :java集合类
4. 模式扩展:
5. 优缺点
五、中介者模式 Mediator Pattern
1. 定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变它们之间地交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
2. 模式结构:
模式角色:Mediator抽象中介者、ConcreteMediator具体中介者、Colleague抽象同事类、ConcreteColleague具体同事类
3. 模式分析:
在中介者模式中,典型的抽象中介者类代码如下:
public abstract class Mediator { protected ArrayList colleagues; public void register(Colleagues colleague) { colleagues.add(colleague); } public abstract void operation(); }
具体中介者:
public class ConcreteMediator extends Mediator { public void operation() { ((Colleague)colleagues.get(0)).method1(); } }
抽象同事类:
public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator;//抽象同事类直接通过构造方法持有中介者的引用,用来调用中介者的方法 } public abstract void method1();//自身方法 public abstract void method2();//在具体类里通过这个调用中介者的方法 }
具体同事类:
public class ConcreteColleague extends Colleague { public ConcreteColleague(Mediator mediator) { super(mediator); } public void method1(){...} public void method2() { mediator.operation1(); } }
ps : 中介者模式是迪米特法则的一个典型应用
4. 模式应用
(1)事件驱动类程序。比如聊天室程序。
(2)Controller作为一种中介者,负责控制视图对象View和模型对象Model之间的交互。
5. 优缺点
中介者模式的主要优点在于简化了对象之间的交互,将各同事解耦,还可以减少子类生成,对于复杂对象之间的交互,通过引入中介者,可以简化各同事类的设计与实现;中介者模式主要缺点在于具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者非常复杂,使得系统难以维护。
六、备忘录模式 Memento Pattern
1. 模式定义
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一个对象行为型模式。别名Token
2. 模式结构
角色:Originator(原发器)、Memento(备忘录)、Caretaker(负责人)
3. 模式分析
七、观察者模式 Observer Pattern
1. 定义
定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫发布-订阅模式。观察者模式是一种对象行为型模式。
2. 模式结构
(1)角色
Subject目标、ConcreteSubject具体目标、Observer观察者、ConcreteObserver具体观察者
(2)类图
主题类持有观察者类的引用,符合条件时调用观察者类的update方法
3. 模式分析
4. 扩展
5. 优缺点
八、状态模式 State Pattern
1. 定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。别名”状态对象“,状态模式是一种对象行为型模式。
九、策略模式 Strategy Pattern
1. 定义
定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式。策略模式是一种对象行为型模式。
2. 模式结构
(1)角色
Context(环境类)、Strategy(抽象策略类)、ConcreteStrategy(具体策略类)
(2)类图
十、模板模式 Template Method Pattern
1. 定义
定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法是一种类行为模式。
2. 模式结构
(1)角色
AbstractClass、ConcreteClass
(2)类图
3. 模式分析
因为模板方法是具体方法,所以抽象层只能是抽象类,而不能是接口。
4. 模式应用
5. 扩展
6. 优缺点
十一、访问者模式 Visitor Pattern
1. 动机
对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生。
为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的模式动机。
2. 定义
表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式是一种对象行为型模式。
3. 模式结构
(1)角色
Vistor、ConcreteVisitor、Element、ConcreteElement、ObjectStructure
(2)类图
4. 模式分析
访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同访问方式访问。在访问者模式中,增加新的访问者无须修改原有系统,系统具有较好的可扩展性。
访问者和客户端,元素和客户端,都是依赖关系。也就是说访问者和元素,通过客户端来实现交互。
以下是访问者的典型代码:
public abstract class Visitor { public abstract void visit(ConcreteElementA eA); public abstract void visit(ConcreteElementB eB); public void visit(ConcreteElementC eC) { //元素C具体操作代码 //如果所有访问者对某一类型的元素的访问操作都相同,可以将操作代码移到抽象访问者中 } } public class ConcreteVisitor extends Visitor { public void visit(ConcreteElementA elementA){//元素A操作代码} public void visit(ConcreteElementB elementB){//元素B操作代码} }
以下是元素类:
public interface Element { public void accept(Visitor visitor); } public class ConcreteElementA implements Element { public void accept(Visitor visitor) { visitor.visit(this); } public void operationA() { //业务方法 } }
最后,对象结构是一个集合,它用于存储元素对象并接受访问者的访问,典型代码如下:
public class ObjectStructure { private ArrayList list = new ArrayList(); public void accept(Visitor visitor) { Iterator i = list.iterator(); while(i.next()) { ((Element)i.next()).accept(visitor); } } public void addElement(Element element) { list.add(element); } public void removeElement(Element element) { list.remove(element); } }
5. 案例
访问者:顾客、收银员、促销员;元素(商品):电脑、手机、书籍。
6. 扩展
倾斜的开闭原则
6. 优缺点
主要优点在于使得增加新的访问操作变得很容易,将有关元素对象的访问行为集中到一个访问对象中,而不是分散到一个元素类中,还可以跨过类的等级结构访问属于不同的等级结构的元素类,让用户能够在不修改现有层次结构的情况下,定义该类层次结构的操作;其主要缺点在于增加新的元素很困难,而且在一定程度上破坏了系统的封装性。