行為型模式(Behavioral Pattern)是對(duì)在不同的對(duì)象之間劃分責(zé)任和算法的抽象化,它是 GoF 設(shè)計(jì)模式中最為龐大的一類模式,包含以下 11 種:模板方法(Template Method)模式、策略(Strategy)模式、命令(Command)模式、職責(zé)鏈(Chain of Responsibility)模式、狀態(tài)(State)模式、觀察者(Observer)模式、中介者(Mediator)模式、迭代器(Iterator)模式、訪問者(Visitor)模式、備忘錄(Memento)模式、解釋器(Interpreter)模式。
本實(shí)驗(yàn)的主要目的如下。
⒈了解 11 種“行為型模式”的定義、特點(diǎn)和工作原理。
⒉理解 11 種“行為型模式”的結(jié)構(gòu)、實(shí)現(xiàn)和應(yīng)用場景。
⒊學(xué)會(huì)應(yīng)用 11 種“行為型模式”進(jìn)行軟件開發(fā)。
行為型模式用于描述程序在運(yùn)行時(shí)復(fù)雜的流程控制,即描述多個(gè)類或?qū)ο笾g怎樣相互協(xié)作共同完成單個(gè)對(duì)象無法單獨(dú)完成的任務(wù),它涉及算法與對(duì)象間職責(zé)的分配。
按照其顯示方式的不同,行為型模式可分為類行為模式和對(duì)象行為模式,其中類行為型模式使用繼承關(guān)系在幾個(gè)類之間分配行為,主要通過多態(tài)等方式來分配父類與子類的職責(zé);對(duì)象行為型模式則使用對(duì)象的組合或聚合關(guān)聯(lián)關(guān)系來分配行為,主要是通過對(duì)象關(guān)聯(lián)等方式來分配兩個(gè)或多個(gè)類的職責(zé)。
由于組合關(guān)系或聚合關(guān)系比繼承關(guān)系耦合度低,滿足“合成復(fù)用原則”所以對(duì)象行為模式比類行為模式具有更大的靈活性。
如果按目的來分,行為型模式共 11 種,每種模式的工作原理在前面的教程中都有詳細(xì)的介紹,每種模式的實(shí)驗(yàn)大概要花 2 個(gè)學(xué)時(shí),大家可以根據(jù)實(shí)驗(yàn)計(jì)劃來選做若干個(gè)實(shí)驗(yàn)。下面以觀察者模式為例,介紹其實(shí)驗(yàn)過程。
觀察者模式是一種對(duì)象行為型模式,用于解決多個(gè)對(duì)象間存在的一對(duì)多的依賴關(guān)系。在現(xiàn)實(shí)世界中,許多對(duì)象并不是獨(dú)立存在的,其中一個(gè)對(duì)象的狀態(tài)發(fā)生改變可能會(huì)導(dǎo)致一個(gè)或者多個(gè)其他對(duì)象也發(fā)生改變,如物價(jià)與消費(fèi)者、股價(jià)與股民、天氣預(yù)報(bào)與農(nóng)民、警察與小偷、事件源與事件處理 者等。這種模式有時(shí)又稱作發(fā)布-訂閱模式、模型-視圖模式,其結(jié)構(gòu)圖如圖 1 所示。
圖1 觀察者模式的結(jié)構(gòu)圖
觀察者模式包含如下角色。
① 抽象主題/目標(biāo)(Subject)角色:提供了一個(gè)用于保存觀察者對(duì)象的聚集類和一個(gè)管理觀察者對(duì)象的接口,它包含了增加、刪除和通知所有觀察者的抽象方法。
② 具體主題/目標(biāo)(Concrete Subject)角色:實(shí)現(xiàn)抽象目標(biāo)中的方法,當(dāng)具體目標(biāo)的內(nèi)部狀態(tài)發(fā)生改變時(shí),通知所有注冊過的觀察者對(duì)象。
③ 抽象觀察者(Observer)角色:定義一個(gè)更新接口,它包含了一個(gè)更新自己的抽象方法。
④ 具體觀察者(Concrete Observer)角色:實(shí)現(xiàn)抽象觀察者定義的更新接口,以便在得到目標(biāo)更改通知時(shí)更新自身的狀態(tài)。
⒈用觀察者模式設(shè)計(jì)一個(gè)交通信號(hào)燈的事件處理程序。
分析:“交通信號(hào)燈”是事件源和目標(biāo),各種“車”是事件監(jiān)聽器和具體觀察者,“信號(hào)燈顏色” 是事件類。
⒉按照以上要求設(shè)計(jì)類圖和編寫 Java 源程序。
所設(shè)計(jì)的實(shí)驗(yàn)程序要滿足以下兩點(diǎn)。
⒈體現(xiàn)“觀察者模式”的工作原理。
⒉符合面向?qū)ο笾械?ldquo;開閉原則”。
⒈用 UML 設(shè)計(jì)“交通信號(hào)燈事件處理程序”的結(jié)構(gòu)圖。
“交通信號(hào)燈事件處理程序”的結(jié)構(gòu)圖如圖 2 所示。
圖2 交通信號(hào)燈事件處理程序的結(jié)構(gòu)圖
⒉根據(jù)結(jié)構(gòu)圖寫出“交通信號(hào)燈事件處理程序”的源代碼。交通信號(hào)燈事件處理程序的源代碼如下。
package observer;
import java.util.*;
public class SignalLightEvent
{
public static void main(String[] args)
{
SignalLight light=new SignalLight();//交通信號(hào)燈(事件源)
light.addVehicleListener(new Car()); //注冊監(jiān)聽器(轎車)
light.addVehicleListener(new Buses());//注冊監(jiān)聽器(公交車)
light.changeColor("紅色");
System.out.println("------------");
light.changeColor("綠色");
}
}
//信號(hào)燈顏色
class SignalColor extends EventObject
{
private String color; //"紅色"和"綠色"
public SignalColor(Object source,String color)
{
super(source);
this.color=color;
}
public void setColor(String color)
{
this.color=color;
}
public String getColor()
{
return this.color;
}
}
//目標(biāo)類:事件源,交通信號(hào)燈
class SignalLight
{
private List listener; //監(jiān)聽器容器
public SignalLight()
{
listener=new ArrayList();
}
//給事件源綁定監(jiān)聽器
public void addVehicleListener(Vehicle vehicle)
{
listener.add(vehicle);
}
//事件觸發(fā)器:信號(hào)燈改變顏色。
public void changeColor(String color)
{
System.out.println(color+"信號(hào)燈亮...");
SignalColor event=new SignalColor(this, color);
notifies(event); //通知注冊在該事件源上的所有監(jiān)聽器
}
//當(dāng)事件發(fā)生時(shí),通知綁定在該事件源上的所有監(jiān)聽器做出反應(yīng)(調(diào)用事件處理方法)
protected void notifies(SignalColor e)
{
Vehicle vehicle=null;
Iterator iterator=listener.iterator();
while(iterator.hasNext())
{
vehicle=iterator.next();
vehicle.see(e);
}
}
}
//抽象觀察者類:車
interface Vehicle extends EventListener
{
//事件處理方法,看見
public void see(SignalColor e);
}
//具體觀察者類:轎車
class Car implements Vehicle
{
public void see(SignalColor e)
{
if("紅色".equals(e.getColor()))
{
System.out.println("紅燈亮,轎車停!");
}
else
{
System.out.println("綠燈亮,轎車行!");
}
}
}
//具體觀察者類: 公交車
class Buses implements Vehicle
{
public void see(SignalColor e)
{
if("紅色".equals(e.getColor()))
{
System.out.println("紅燈亮,公交車停!");
}
else
{
System.out.println("綠燈亮,公交車行!");
}
}
}
⒊上機(jī)測試程序,寫出運(yùn)行結(jié)果。
交通信號(hào)燈事件處理程序的運(yùn)行結(jié)果如下:
紅色信號(hào)燈亮...
紅燈亮,轎車停!
紅燈亮,公交車停!
------------
綠色信號(hào)燈亮...
綠燈亮,轎車行!
綠燈亮,公交車行!
⒋按同樣的步驟設(shè)計(jì)其他“觀察者模式”的程序?qū)嵗?/p>
⒌寫出實(shí)驗(yàn)心得。