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