劉 雋 張 輝
軟件設(shè)計模式在鐵路調(diào)度指揮系統(tǒng)中的應(yīng)用
劉 雋*張 輝**
介紹設(shè)計模式的概念以及封裝變化的思想,結(jié)合鐵路調(diào)度指揮系統(tǒng)的特點(diǎn),詳細(xì)說明了工廠方法、觀察者和單件模式的典型應(yīng)用場景,以及設(shè)計模式的綜合應(yīng)用。
設(shè)計模式;鐵路調(diào)度指揮;系統(tǒng)
軟件設(shè)計模式(Design Patterns)是為解決軟件開發(fā)領(lǐng)域中多種重復(fù)出現(xiàn)的經(jīng)典問題而提出的解決方案,是面向?qū)ο缶幊探?jīng)驗(yàn)的總結(jié),是軟件設(shè)計技巧中最重要的方法和原則。軟件設(shè)計需要應(yīng)付不斷變化的需求,項目開發(fā)需要不斷的反復(fù)修改更新,解決之道就是封裝變化。設(shè)計模式是“封裝變化”思想的最佳闡釋,就是尋找軟件中可能存在的“變化”,然后利用抽象對這些變化進(jìn)行封裝。由于抽象沒有具體的實(shí)現(xiàn),代表了一種無限的可能性,使得軟件系統(tǒng)能夠以擴(kuò)展的方式滿足未來的需求變化。
鐵路調(diào)度指揮系統(tǒng)屬于企業(yè)級綜合性應(yīng)用系統(tǒng),包括信息化管理和實(shí)時執(zhí)行控制2大部分,即“管控結(jié)合”、“運(yùn)維融合”類型的計算機(jī)應(yīng)用系統(tǒng)。其主要功能是實(shí)現(xiàn)設(shè)備設(shè)施監(jiān)視與控制,各類調(diào)度指揮計劃的編制、調(diào)整、執(zhí)行與反饋,以及調(diào)度系統(tǒng)自身的狀態(tài)維護(hù)。目前,中國鐵路已進(jìn)入高速發(fā)展時代,規(guī)章制度、指揮流程、調(diào)度崗位、線路、車輛總在變化,因此鐵路調(diào)度指揮系統(tǒng)也要與時俱進(jìn),適應(yīng)變化。這也恰好契合了軟件開發(fā)領(lǐng)域“擁抱變化”的主題。
設(shè)計模式從創(chuàng)建、結(jié)構(gòu)、行為三方面提出了封裝變化的方案,而鐵路調(diào)度指揮系統(tǒng)經(jīng)常要面對設(shè)備種類與數(shù)量的變更、流程的改善、自身部署規(guī)模的增加。因此設(shè)計模式在鐵路專業(yè)軟件開發(fā)領(lǐng)域是有合適的切入點(diǎn)的。
筆者有幸參與過一些鐵路調(diào)度指揮系統(tǒng)項目,其中包括列車調(diào)度指揮系統(tǒng)(TDCS)、分散自律調(diào)度集中系統(tǒng)(CTC)、客運(yùn)專線運(yùn)營調(diào)度系統(tǒng)(TDS)、編組站綜合自動化系統(tǒng)(SAM)、動車基地調(diào)度集中系統(tǒng)(ACS)。下面總結(jié)設(shè)計模式在鐵路調(diào)度指揮系統(tǒng)中的一些典型應(yīng)用,與大家分享經(jīng)驗(yàn)。
工廠方法屬于創(chuàng)建型設(shè)計模式,用于封裝對象創(chuàng)建所引起的可能變化。工廠方法模式結(jié)構(gòu)如圖1所示。
圖1 工廠方法模式結(jié)構(gòu)
意圖:定義一個用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個類。工廠方法使一個類的實(shí)例化延遲到其子類。
適用性:當(dāng)一個類不知道其所必須創(chuàng)建的對象類的時候;當(dāng)一個類希望由其子類來指定所創(chuàng)建對象的時候;當(dāng)類將創(chuàng)建對象的職責(zé)委托給多個幫助子類中的某一個,并且希望將哪個幫助子類是代理者這一信息局部化的時候。
準(zhǔn)確的說,工廠方法模式是將創(chuàng)建對象實(shí)例的責(zé)任轉(zhuǎn)移到工廠類中,并利用抽象的原理將實(shí)例化行為延遲到具體工廠類。在鐵路調(diào)度指揮系統(tǒng)中,對設(shè)備的管理是一項主要功能,因而在軟件中創(chuàng)建設(shè)備對象就是實(shí)施管理的第一步。
在SAM系統(tǒng)中,電務(wù)維護(hù)服務(wù)器軟件需要從局域網(wǎng)中接收大量各種類型設(shè)備和操作的實(shí)時信息,在進(jìn)行歸類整理并生成數(shù)據(jù)對象后,或存儲,或轉(zhuǎn)發(fā),或圖形化展示。由于設(shè)備類型、操作內(nèi)容會隨用戶需求的發(fā)展而變化,為了將變化給軟件修改和維護(hù)帶來的影響減少至最低程度,應(yīng)該采用工廠方法對生成數(shù)據(jù)對象這一過程進(jìn)行封裝。
圖2中的CCodeData、COperationData和CStatusData分別代表聯(lián)鎖碼位信息類、用戶操作信息類和設(shè)備狀態(tài)信息類,工廠方法通過對應(yīng)的CCodeDataFactory、COperationDataFactory和CStatusData-Factory這些工廠類以抽象方法來創(chuàng)建具體的信息類對象。再結(jié)合反射、配置文件、表啟動法等輔助技術(shù),最終就可以徹底達(dá)到解除對具體對象依賴的目標(biāo)。
圖2 SAM系統(tǒng)中的工廠方法模式類圖
假設(shè)未來需要電務(wù)維護(hù)服務(wù)器接收并處理一種新類型的實(shí)時信息,那么只需為其增加一個CData-Base的子類和一個對應(yīng)的CDataFactoryBase子類即可,軟件的其他部分無需改動。
觀察者屬于行為型設(shè)計模式,對可能變化的行為進(jìn)行抽象,通過封裝達(dá)到整個架構(gòu)的可擴(kuò)展性。圖3是觀察者模式結(jié)構(gòu)。
意圖:定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。
圖3 觀察者模式結(jié)構(gòu)
適用性:當(dāng)一個抽象模型有2個方面,其中一個方面依賴于另一方面,將這二者封裝在獨(dú)立的對象中,以使它們可以各自獨(dú)立地改變和復(fù)用;當(dāng)一個對象的改變需要同時改變其他對象,而不知道具體有多少對象有待改變;當(dāng)一個對象必須通知其他對象,而它又不能假定其他對象是誰。換言之,不希望這些對象是緊密耦合的。
觀察者模式中最關(guān)鍵的一點(diǎn)是需要對觀察者角色進(jìn)行抽象,解除觀察者與被觀察者之間的依賴關(guān)系。此外,被觀察者即主體(Subject)角色,還需要維護(hù)一個集合對象,它是一個觀察者對象的列表集合,在消息通知時,被觀察者將遍歷該集合內(nèi)的觀察者對象,并調(diào)用它們的相關(guān)方法。
在.NET框架中,由于引入了委托與事件機(jī)制,為實(shí)現(xiàn)觀察者模式提供了一個更簡捷的方案。事件的發(fā)布者就是主體角色;事件的訂閱者則為觀察者角色。
在調(diào)度指揮系統(tǒng)的用戶需求中,要求系統(tǒng)軟件對鐵路設(shè)備的工作狀態(tài)進(jìn)行不間斷監(jiān)視,比如在部署CTCS-2級和CTCS-3級列控系統(tǒng)的線路上,TDCS、CTC和ACS等系統(tǒng)都能夠動態(tài)顯示列控中心的綜合狀態(tài)。需求分析的結(jié)果是,系統(tǒng)終端能夠收到列控中心發(fā)來的狀態(tài)信息;依據(jù)狀態(tài)信息在相關(guān)窗體界面上查找到對應(yīng)的控件;找到控件后,根據(jù)當(dāng)前狀態(tài)信息修改控件的顏色。
這里存在一個問題:終端應(yīng)該在更新時查詢窗體是否已被關(guān)閉,如果已關(guān)閉則無需查找并更新控件。但是,這樣勢必要增加狀態(tài)信息處理模塊對窗體模塊的依賴關(guān)系,這是軟件設(shè)計者不希望看到的情況。如果使用觀察者模式來實(shí)現(xiàn)這一功能,就會大大減弱這種依賴關(guān)系,達(dá)到事半功倍的效果。
綜合狀態(tài)數(shù)據(jù)模塊是主體,其中定義了更新事件,并能夠主動引發(fā)事件;監(jiān)視窗體是觀察者,能夠主動訂閱/取消訂閱更新事件,而被動接收事件通知來更新顯示內(nèi)容。二者之間具體的交互過程:監(jiān)視窗體會在啟動后訂閱更新事件,在關(guān)閉前取消訂閱;通信模塊依據(jù)收到的狀態(tài)信息來更新數(shù)據(jù)模塊,然后調(diào)用數(shù)據(jù)模塊中的事件引發(fā)方法;事件被引發(fā)后,訂閱事件的窗體即獲得了通知,它會按照數(shù)據(jù)模塊中的內(nèi)容來刷新控件顯示;無論窗體是否啟動,通信模塊都要更新數(shù)據(jù)模塊,如果窗體未啟動或者已關(guān)閉,事件對象維護(hù)的觀察者列表中就沒有記錄,因此事件通知就不會發(fā)給窗體。
從上述過程中可以看出,通信模塊和數(shù)據(jù)模塊根本不需要知道窗體是否存在,這樣就達(dá)到了解耦依賴關(guān)系,以及動態(tài)確定是否刷新控件的目的。
單件屬于創(chuàng)建型設(shè)計模式,它是將創(chuàng)建單件對象的實(shí)現(xiàn)邏輯封裝起來。圖4是單件模式結(jié)構(gòu)。
意圖:保證一個類僅有一個實(shí)例,并提供一個訪問它的全局訪問點(diǎn)。
適用性:當(dāng)類只能有一個實(shí)例,而且客戶可以從一個眾所周知的訪問點(diǎn)訪問時;當(dāng)這個惟一實(shí)例應(yīng)該是通過子類化可擴(kuò)展的,并且客戶應(yīng)該無需更改代碼就能使用一個擴(kuò)展的實(shí)例時。
單件模式將那些可能重復(fù)的實(shí)現(xiàn)邏輯封裝為方法或單獨(dú)的類,則可以避免因這些實(shí)現(xiàn)的變化而導(dǎo)致代碼所謂“霰彈式修改”(Shotgun Surgery)。
鐵路領(lǐng)域的許多設(shè)備是惟一標(biāo)識的,在調(diào)度指揮系統(tǒng)中對應(yīng)的映像也應(yīng)該具有惟一性,調(diào)度指揮系統(tǒng)也需要對一類資源或數(shù)據(jù)以獨(dú)占的方式進(jìn)行使用。在這2個場景中,都可以用到單件模式。
調(diào)度指揮系統(tǒng)一般都提供語音提示功能,而且系統(tǒng)中的不同功能模塊都需要向使用者發(fā)出語音提示,比如聯(lián)鎖和列控設(shè)備的管理模塊要廣播設(shè)備報警信息,調(diào)度作業(yè)模塊要播放執(zhí)行進(jìn)度。為了避免互相干擾,不同模塊的語音提示不能同時并發(fā)播出,而應(yīng)該按照一定的優(yōu)先級順序播出。
為滿足上述需求,應(yīng)該為系統(tǒng)設(shè)計一個以單件形式存在的通用語音提示模塊。所有需要播出語音提示的模塊都通過惟一的訪問點(diǎn)來調(diào)用它,并且要由該模塊獨(dú)立地維護(hù)多條語音提示的播放時機(jī)和順序。如果未來對語音提示有新的需求,只需對這個單一的通用模塊進(jìn)行修改即可。
在.NET平臺上,可以運(yùn)用靜態(tài)類、靜態(tài)數(shù)據(jù)成員,結(jié)合靜態(tài)構(gòu)造器的初始化能力來實(shí)現(xiàn)單件模式。如果再輔以多線程技術(shù),就可以得到一個具備后臺播放功能的通用語音提示模塊。
為了應(yīng)對某個復(fù)雜的需求,有時需要將多種設(shè)計模式組合起來,形成復(fù)合的設(shè)計模式。這個過程需要根據(jù)項目的實(shí)際需求,逐步演化設(shè)計。
SAM系統(tǒng)電務(wù)維護(hù)服務(wù)器中,不僅應(yīng)用了工廠方法設(shè)計模式,而且為了確保那些具體的工廠類具有惟一的訪問點(diǎn),節(jié)省計算資源,可以對這些工廠類施加單件模式。同樣地,在采用觀察者模式設(shè)計的列控中心綜合狀態(tài)數(shù)據(jù)模塊上,也可以疊加單件模式,這樣就能夠保證列控中心在系統(tǒng)中具有惟一的映像。
學(xué)習(xí)并使用設(shè)計模式是為了改善設(shè)計,讓軟件能夠經(jīng)受需求不斷變化的考驗(yàn)。設(shè)計模式不是衡量軟件開發(fā)者水平的一把標(biāo)尺,不用設(shè)計模式同樣可以做出好的設(shè)計。不過,若能掌握并合理運(yùn)用設(shè)計模式,對提高設(shè)計能力、增強(qiáng)鐵路調(diào)度指揮系統(tǒng)的穩(wěn)定性和安全性是非常有益的。
[1] 張逸.軟件設(shè)計精要與模式.第2版[M].北京:電子工業(yè)出版社.
[2] Eric Gamma,Richard Helm,Ralph Johnson,John Vlissides(GOF)著.李英軍等譯.設(shè)計模式——可復(fù)用面向?qū)ο筌浖幕A(chǔ)[M].北京:機(jī)械工業(yè)出版社.
[3] Martin Fowler.UML Distilled:A Brief Guide to the Standard Object Modeling Language(3rd Edition).Addison-Wesley.
[4] Martin Fowler.Refactoring:Improving the Design of Existing Code.Addison-Wesley
[5] JAVA愛好者h(yuǎn)ttp://www.javafan.net.
[6] Jeffrey Richter著.李建忠譯.Microsoft.NET框架程序設(shè)計(修訂版)[M].北京:清華大學(xué)出版社.
[7] Daniel Solis著.Illustrated C#2008.Apress
The authors firstly introduced the concept of design patterns and the thoughtof change of encapsulation.Based on the features of railway dispatching&command systems,the model scenario of three design patterns,namely factory method,observer,and singleton were illustrated and the synthetic application of design patterns were dealtwith.
Design Patterns;Railway Dispatching&Command;System
中國鐵道科學(xué)研究院通信信號研究所 100081 北京
*助理研究員 **研究實(shí)習(xí)員
2011-01-21
(責(zé)任編輯:諸紅)