设计模式笔记(四):行为型模式

行为型模式:

1.划分类和对象的职责,研究系统在运行时实例对象之间的交互。

2.类行为型模式使用继承关系在几个类之间分配行为

3.对象行为型模式使用对象的聚合关联分配行为,大部分行为型设计模式属于对象行为型设计模式

一、职责链模式

1.定义

避免请求发送者与接收者耦合,将多个可能接受请求的对象连接成一条链,沿这条链传递请求,直到有对象处理它位置。职责链模式是一种对象行为型模式。

2.角色

Handler:抽象处理者。一个处理请求的接口(一般设计为抽象类),其中声明了抽象请求处理方法;因为每个处理者的下家还是处理者,所有在其中定义一个Handler类对象(维护一个对下家的引用)

ConcreteHandler:具体处理者。其中实现抽象处理者定义的抽象请求处理方法。方法内,先判断是否有相应处理权限,若有则处理请求,若无则将请求转发给后继者(调用链中下家的请求处理方法)。

3.结构

Handler中定义方法

public void setSuccessor(Handler successor){ this.seccesor = seccessor; }

用于客户端调用创建链

4.模式分析

职责链模式并不创建职责链,一般在客户端创建(创建职责链的各个对象,依次setSuccessor)

5.模式优点

1)请求对象仅需维持一个指向后继者的引用,无需维持它对所有候选处理者的引用,简化对象的相互连接。

2)增加新的具体请求者时无需修改源码,只需在客户端重新创建链,符合“开闭原则”

6.本质:分离职责,动态组合

二、命令模式

1.定义

将一个请求封装为一个对象。引入了命令类,降低发送者和接收者的耦合度。请求发送者指定一个命令对象,通过命令对象调用请求接收者的处理方法。

2.角色

Command:抽象命令类(抽象类或接口)。其中声明execute()等方法,用于调用请求接收者的相关操作

ConcreteCommand:具体命令类实现Command中声明的所有方法。对应具体的接收者对象(维护一个对Receiver对象的引用),在execute()方法中调用接收者对象的action()

Invoker:请求发送者。因为一个请求发送者不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系(维护一个对Command的引用)。程序运行时传入一个ConcreteCommand对象(构造传入和设值传入),调用其execute()方法,间接调用Receiver的action()

Receiver:请求接收者。action()具体实现对请求的业务处理

3.结构

4。模式分析

一般一个请求发送者不止发送一个请求,增加一个CommandQueue类存储多个命令对象(ArrayList),不同命令对象可对应不同的请求接收者,excute()方法中循环调用每一个Command对象的excute()方法。在Invoker类中维护一个CommandQuene对象的引用。

5.本质:封装请求

6.举例

电视机遥控

三、解释器模式

四、迭代器模式

1.定义

1)将遍历数据的行为从聚合对象中分离出来,并封装在一个被称为迭代器的对象中(提供一种方法来访问聚合对象,而不暴露这个对象的内部表示)是一种对象行为型模式。

2)包含聚合和迭代器两个层次结构,在迭代器模式中应用工厂方法模式

2.角色

Iterator:抽象迭代器,定义了访问和遍历元素的接口,声明了相应方法。

ConcreteIterator:具体迭代器,实现Iterator。维护一个对ConcreteAggregate对象的引用(构造传入)。通过游标记录(int)在聚合对象中所处的当前位置。

Aggregate:抽象聚合类。声明创建迭代器对象方法。

ConcreteAggregate:具体聚合类。存储数据、实现createIterator方法,用于返回一个具体迭代器对象

3.结构

4.模式分析

1)Iterator中包含太多方法会给子类实现带来麻烦,可以考虑使用抽象类设计抽象迭代器(为每个方法提供给一个空的默认实现)

2)具体迭代器和具体聚合类存在双重关系。其中关联关系:ConcreteIterator维持一个对ConcreteAggregate对象的引用(用于访问其中的数据)。依赖关系:ConcreteAggregate中有创建并返回ConcreteIterator的方法(具体聚合类中并没有维护一个具体迭代器类对象的引用)

为了让迭代器可以访问聚合对象中的数据,除了使用关联关系,还可以将迭代器设计为聚合类的内部类。

5.模式本质:控制访问聚合对象中的元素

6.举例

很有意思的依赖和关联关系

//ConcreteIterator的构造器
public ConcreteIterator(ConcreteAggregate aggregate){
    this.aggregate = aggregate;
}

//ConcreteAggregate实现创建迭代器方法
public Iterator createConcreteIterator(){
    return new ConcreteIterator(this);
}

//客户端
//先创建聚集类对象
ConcreteAggregate a = new ConcreteAggregate();
//此处省略一些add to a操作
//获取迭代器的方式
Iterator i = new ConcreteIterator(a);
//或者
Iterator i = a.createConcreteIterator();

五、中介者模式(调停者模式)

1.定义

用一个中介对象来封装一系列的对象交互。中介者模式是一种对象行为型模式。

2.角色

Mediator:抽象中介者。定义一个接口用于同事对象之间相互通信。

ConcreteMediator:具体中介者。实现Mediator接口中的方法,维持对各个同事对象的引用。

Colleague:抽象同事类。定义同时类共有的方法,并声明了一些抽象方法。维持一个对Mediator的引用(构造传入或设值传入),其子类通过该引用来与中介者通信。

ConcreteColleague:具体同事类。实现Colleague中的抽象方法。通过中介者来间接完成与其他同事类的通信,定义依赖方法,调用自身引用的mediator的operation()。可能还有自身方法,用于处理自身行为。

3.结构

4.模式分析

Mediator可以设置成一个抽象类:定义一个Colleage类集合,用于存储同事对象,提供增加同事对象的方法,声明具体中介者将实现的方法

5.本质:封装交互

六、备忘录模式

1.定义

在不破坏封装的前提下捕获一个对象的内部状态,并在这个对象之外保存这个状态,这样可用在以后将对象恢复到原先保存的状态。备忘录模式是一种对象行为型模式。

别名Token

2.角色

Originator:原发器。需要保存内部状态的类。定义创建备忘录方法(传入的参数为自身)存储自身当前内部状态。原发器决定保存哪些内部状态,定义恢复原发器状态方法(根据备忘录存储的state)

Memento:备忘录,存储原发器内部状态。通常提供与原发器相对应的属性(部分或全部)。

Caretaker:负责人。负责保存备忘录,存储一个或多个备忘录对象。只负责存储,不能对备忘录内容进行操作和检查,不知道备忘录对象内部细节。

3.结构

4.模式分析

1)除原发器本身和负责人之外,备忘录不能供其他类使用。

     C++中,通过让原发器类和备忘录类成为友元类,让其互相之间可访问对象的一些私有属性

     Java中,通过将原发器类和备忘录类定义在同一个包中来实现封装,使用默认访问标识符来定       义备忘录类,或者将备忘录类作为原发器类的内部类

2)实现多次撤销:负责人类中定义一个集合存储多个备忘录

5)本质:保存和恢复内部状态

七、观察者模式

1.定义

定义对象间一种一对多的依赖关系,使当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。观察者模式是一种对象行为型模式。

一个观察目标(发生改变的对象),多个观察者(被通知的对象),观察者之间可以没有任何关系。

2.角色

Subject:(可以是接口、抽象类、具体类)目标(主题),指被观察的对象。定义一个观察者集合,提供增加、删除观察者的方法,声明通知方法notify()

ConcreteSubject:具体目标类,包含经常改变的数据。实现notify()方法(遍历观察者集合,调用每一个观察者的响应方法)。无需扩展目标类时,具体目标类可省

Observer:(一般定义为接口)抽象观察者,声明更新数据的方法

ConcreteObserver:具体观察者,实现Observer中更新数据的方法。

3.结构

4.模式分析

1)抽查观察类中定义一个观察者集合用于存储所有观察者对象

2)有些情况下,具体观察类的update()方法在执行时需要使用到具体目标类中的状态属性,因此在具体观察类中维护一个指向ConcreteSubject对象的引用(例如调用其attach()方法或detach()方法将自己添加到目标类集合或从其中删除)

3)不需要时,具体观察类和具体目标类之间无需维持对象引用

5.本质:触发联动

八、状态模式

1.定义

将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使对象状态可以灵活变化。客户端无须关心对象状态,对于任何状态的对象,客户端统一处理。

2.角色

Context:环境类(上下文类),是拥有多种状态的对象(真正的对象)。维护一个State类实例的引用,这个实例定义当前状态

State:抽象状态类。定义一个接口以封装一个特定状态下相关的行为。相同行为可以写在抽象状态类中,声明一个不同状态对于不同行为的抽象方法

ConcreteState:具体状态类。每一个具体状态类对应一种具体状态,实现特定的handle()方法

3.结构

4.模式分析

1)上图中,Context与State之间存在单向关联关系(Context中定义了一个State对象),实际使用时,它们之间可能存在更为复杂的关系(依赖关系或关联关系)

2)一个对象的状态之间可以进行还相互转换,有两种方式:

    1° 统一由Context类负责,它充当状态管理器角色。类中定义方法,通过对自身某些属性值的判          断调用自身方法this.setState(),实现状态转换

    2° 由ConcreteState类来负责。通过判断Context的某些属性值为它设置新的态对象(调用                   context对象的setState()方法)。此时,两者存在依赖或关联关系

5.本质:根据状态来分离和选择行为

九、策略模式

1.定义

定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。是一种对象行为型模式。

2.角色

Context:环境类,使用算法的角色。维持一个对抽象策略类的引用实例,通过调用其algorithm方法来调用具体算法

Strategy:(可以是接口、抽象类、具体类)抽象策略类,声明抽象方法(所支持的算法)

ConcreteSrategy:具体策略类,覆盖父类定义的algorithm()方法,使用具体算法实现业务处理

3.结构

和状态模式很像

4.模式分析

1)策略模式把算法的责任和算法本身割开,通常把一系列算法封装到一系列具体策略类里

2)在一个系统中可以存在多个环境类,它们可能重用一些相同的算法

3)策略模式仅仅封装算法,不决定在何时使用算法,算法的使用由客户端决定(客户端需要理解具体策略间的区别,这是策略模式的缺点之一)

4)优点:完美支持“开闭原则”

5.模式使用:

 a.创建抽象策略类,声明抽象方法algorithm();

 b.创建具体策略类,实现具体算法

 c.创建Context类,维持一个对抽象策略类的引用,定义setStrategy(AbstractStrategy strategy)方      法,定义algorithm()方法(方法体内调用引用的具体策略对象的算法)

6.本质:分离算法、选择实现

十、模板方法模式

基本方法:实现功能的每一个步骤所对应的方法

模板方法:调用这些基本方法的同时定义基本方法的执行次序

1.定义

定义一个操作中算法的框架,将一些步骤延迟到子类中。使子类可以不改变算法的结构即可重定义该算法中的某些特定步骤。是一种类行为型模式。

2.角色

AbstractClass:抽象类定义一系列基本方法(可以使具体的也可以是抽象的),每个基本操作对应算法的一个步骤,子类可以重定义或实现这些步骤。同时,抽象类实现了一个模板方法(定义了一个算法框架)

ConcreteClass:具体子类,实现抽象类中声明的抽象操作方法,完成子类特定的算法步骤,也可以覆盖抽象类中已实现的操作

3.结构

4.模式分析

1)由于模板方法是具体方法,抽象层只能是抽象类,不能是接口

2)模板方法给出了一个顶层逻辑框架,逻辑的组成步骤(定义基本方法的调用顺序的方法)在抽象类中可以是具体方法,也可以是抽象方法

3)基本方法的分类

a.抽象方法:抽象类中声明、具体子类实现

b.具体方法:抽象类中声明并实现或者具体类中声明并实现,子类进行覆盖或直接继承

c.钩子方法:抽象类中声明并实现或者具体类中声明并实现,子类加以扩展。通常在父类中给出一个空实现作为默认实现(也可以非空)

对于所有子类都相同的基本方法可在父类提供具体实现,否则在父类声明为抽象方法或钩子方法,由不同子类提供不同实现

5.本质:固定算法骨架

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值