肖永剛
(文山學院計科系,云南文山663000)
校園中存在著許多的對象,例如校園、教師、學生等,這些對象代表著真實校園中的各種實體。在真實的校園中消息是這樣傳遞的,首先校園有了一個消息,它需要將這個消息通知教師,再由教師將這個消息通知學生?;蛘?,教師有了一個消息,他需要將這個消息通知學生,但不必將這個消息通知校園。消息總是從較高的層次向較低的層次傳遞,不會反向的從較低的層次向較高的層次傳遞。這是一種自頂向下式的消息傳遞機制。
同樣的,在設(shè)計虛擬校園[1]時,也要實現(xiàn)這樣的一種消息傳遞方式。校園、教師和學生等對象構(gòu)成了整個虛擬校園的基本元素。文章只介紹了這三者之間的消息傳遞機制,以簡化需要討論的問題。
觀察者模式[2]在對象之間定義了一種一對多的依賴關(guān)系。當一個對象(發(fā)布者)的狀態(tài)發(fā)生變化時,其它的對象(觀察者),會馬上感知或接受到這種變化,所以觀察者模式在開發(fā)虛擬校園時非常有用。對比兩種設(shè)計虛擬校園的方法,一種沒有使用觀察者模式,而只是基于組合原則來構(gòu)建系統(tǒng),另一種應(yīng)用了觀察者模式來設(shè)計開發(fā)虛擬校園,在校園、教師和學生三個對象之間建立起一對多的依賴關(guān)系。文章用對比的方式來說明應(yīng)用觀察者模式設(shè)計帶來的好處[3]。
類圖如圖1所示,校園、教師和學生通過組合的方式聯(lián)系在一起,組合原則廣泛地應(yīng)用于這個設(shè)計中。Campus類包含一個實體變量teachers,用來代表教師對象,即消息要傳遞給誰。Teacher類包含一個實體變量students,代表學生對象,即要繼續(xù)將消息傳遞給誰。三個類之間通過變量teachers和變量students進行訪問。
圖1 應(yīng)用組合方式構(gòu)建的系統(tǒng)
序列圖[4]如圖2所示,系統(tǒng)生成參與消息傳遞的對象,分別屬于 Campus、Teacher和 Student類。在對象內(nèi)部已經(jīng)指定了消息的發(fā)送者和接受者,在系統(tǒng)運行的過程中不會也不能更改它們。首先Campus類產(chǎn)生一個消息并將它傳遞給Teacher類,通過調(diào)用Campus類的broadcast方法實現(xiàn)。然后Teacher類接受這個消息并將它傳遞給Student類,通過調(diào)用Teacher類的 receiveMessage和 broadcast方法實現(xiàn)。最后Student類接受這個消息,通過調(diào)用Student類的receiveMessage方法實現(xiàn)。這樣的方式可以實現(xiàn)消息的自頂向下的傳遞,滿足系統(tǒng)設(shè)計的要求。
圖2 應(yīng)用組合方式時的序列圖
但是這種設(shè)計方式有它的不足之處。一方面,當要擴展虛擬校園的功能時,比方說增加一些對象,這些對象同樣要參與到消息傳遞的過程當中,此時就需要對已有類的定義代碼進行修改,定義更多的實體變量來代表新加入的對象。當加入到系統(tǒng)中的對象越來越多時,這種修改的工作量將變得很大。產(chǎn)生錯誤的幾率也隨之增加,系統(tǒng)的可維護性變得很差。另一方面,這個設(shè)計中沒有提供一種靈活的更改消息發(fā)送或接受對象的方法。在系統(tǒng)運行時,不能動態(tài)的將對象加入到消息傳遞過程中,或從消息傳遞過程中將對象移除,因為這些都是在類的定義中預(yù)先指定了的。通過這種方式設(shè)計的系統(tǒng)缺少靈活性。
應(yīng)用觀察者模式重新設(shè)計了虛擬校園,系統(tǒng)在可擴展性和靈活性上都獲得很大的提高,類圖如圖3所示,Campus類是發(fā)布者;Teacher類有兩個身份,既可以是發(fā)布者又可以是觀察者,Student類只能作為觀察者。當Campus類或者Teacher類發(fā)送消息時,它們相應(yīng)的觀察者將會收到消息。采用這樣的設(shè)計方式,整個系統(tǒng)的靈活性得到了提高。只要一個對象實現(xiàn)了發(fā)布者接口,它就可以是發(fā)布者,不管這個對象實際上是做什么的[5]。同樣,只要一個對象實現(xiàn)了觀察者接口,它就可以是觀察者。所以,當要擴展系統(tǒng)功能時,可以很方便地添加一些實現(xiàn)了這兩種接口的類,而不需要對已有的類進行修改。唯一需要保證的是,這些類實現(xiàn)了相應(yīng)的接口。
圖3 應(yīng)用觀察者模式構(gòu)建的系統(tǒng)
虛擬校園系統(tǒng)在校園、教師和學生之間建立了兩個一對多的依賴關(guān)系。一個是Campus類與Teacher類,Teacher類依賴Campus類傳遞消息;另一個是Teacher類與 Student類,Student類依賴 Teacher類傳遞消息。Teacher類扮演了兩種身份,既是消息的接受方又是消息的發(fā)送方。
在Subject接口中,方法attach用來注冊觀察者,detach用來注銷觀察者,方法notify用來通知觀察者;在Observer接口中,方法receiveMessage用來接受消息。在Campus類中,變量observers用來代表消息的觀察者列表,方法getMessage用來產(chǎn)生新的消息;在Teacher類中,變量observers用來代表消息的觀察者列表,變量campus用來代表消息的發(fā)布者,方法getMessage用來產(chǎn)生新的消息;在Student類中,變量campus用來代表消息的發(fā)布者,方法get-Message用來產(chǎn)生新的消息。
序列圖如圖4所示,當Campus類傳遞消息之前,它需要調(diào)用attach和detach方法決定消息由誰接受。一旦產(chǎn)生一條消息,它首先將這條消息傳遞給Teacher類,Teacher類收到消息后,也需要調(diào)用attach和detach方法決定消息由誰接受,再將這條消息傳遞給Student類。這樣,通過動態(tài)的注冊和注銷觀察者,以及利用不同對象之間方法的依次調(diào)用,實現(xiàn)了消息自頂向下的傳遞。
圖4 應(yīng)用觀察者模式時的序列圖
總體來看,應(yīng)用設(shè)計者模式的優(yōu)點大于缺點。首先,系統(tǒng)獲得良好的可擴展性,可以很容易的向系統(tǒng)中添加新的對象,需要做的只是要那些新加入的對象實現(xiàn)Subject接口或Observer接口,然后,可以在需要它們進行消息傳遞的時候注冊到觀察者列表,在不需要進行消息傳遞的時候注銷出觀察者列表。其次,對于本系統(tǒng)中參與消息傳遞的對象,因為發(fā)布者和觀察者之間并不存在很緊密的聯(lián)系,它們可以獨立地應(yīng)用在其它的系統(tǒng)中。對其中某個對象的復用不受到另外對象的影響或限制。最后,如果對某個對象進行了修改,不會影響其它的對象,不需要修改已有的對象。所以,采用了觀察者模式重新設(shè)計以后,系統(tǒng)獲得了良好的可擴展性和靈活性,有利于系統(tǒng)的修改和維護。
可以看到,重新設(shè)計以后將會帶來更多的接口和方法。每個發(fā)布者或接受者都需要某個接口去定義。但是對于一個項目來說,這可能會帶來管理上的困難,因為跟蹤或維護這些類的工作量會增多。
[1] 劉巧紅.計算機虛擬校園的建造與人機交互的實現(xiàn)[J].計算機工程與設(shè)計,2006,(19):4332 -4335.
[2] Eric Freeman,Elisabeth Freeman,Kathy Sierra & Bert Bates.Head First Design Patterns[M].USA:O’reilly Media,2004:51.
[3] 廖志堅,蔣明亮.設(shè)計模式在廣東高新區(qū)產(chǎn)業(yè)地圖研究系統(tǒng)中的應(yīng)用[J].科技管理研究,2011,(2):123-126.
[4] Dan Pilone& Russ Miles.Head First Software Development[M].USA:O’reilly Media,2007:436-437.
[5] Kathy Sierra& Bert Bates.Head First Java[M].USA:O’reilly Media,2007:226.