摘要:在軟件系統開發中,不同模塊間需要進行信息的交互、數據的傳遞,并處理不同情況發生時的邏輯關系。尤其涉及多級模塊協調同步時,這種協同響應機制就更為復雜。基于Java語言的屬性事件協同技術能有效處理此類問題。通過構造共享的屬性事件池,利用事件的觸發與響應機制實現不同模塊間的協同溝通。對該技術的構思、技術過程及基于Java語言的實現進行了介紹。
關鍵詞:Java; 屬性事件; 協同技術; 多線程
中圖分類號:TP14文獻標志碼:A
文章編號:1001-3695(2007)11-0079-03
當前大部分軟件的開發均采用模塊化技術。然而,在模塊化程序設計中很重要的工作就是模塊間協調關系的邏輯處理,即當某情形出現時相關功能模塊如何得到通知,如何順序與并發工作,如何交換數據等。這一環節處理得好壞直接影響軟件的性能、質量、效率與編寫工作量。本文基于Java語言,提出一種基于屬性事件的模塊間協同與數據交互技術。利用該技術可以使模塊間協同的邏輯復雜性大大簡化,可以很容易地實現程序的邏輯協調。
1技術的構思
模塊間進行協調通信時有三個因素是非常重要的。一是條件滿足時通知的下達與接收;二是條件滿足時不同模塊進行響應運作所需要的信息與數據;三是對該條件感興趣模塊的集合如何管理。尤其前兩個因素是模塊對外部運作進行感知與響應的必備條件,是執行分布式事務的基礎。
在Java語言中,基于屬性事件的協同技術的思路如圖1所示。所謂的屬性事件是通過事件對象封裝的幾個對象參數。它定義了事件的標志,并保存了事件觸發時的現場數據。要實現基于屬性事件的協同技術,首先需要構造一個屬性事件代理。它包括屬性事件池與事件觸發器兩個部分。屬性事件代理實現兩個主要功能:接受感興趣者的監聽注冊(只有注冊的模塊才可能接收到觸發的屬性事件);提供事件觸發器,允許其他模塊利用觸發器觸發某一類型的屬性事件[1~5]。
利用屬性事件代理功能,某一功能的邏輯過程就不需要由某一功能模塊來實現,而是通過屬性事件的觸發與響應來構造。當某一模塊需要與另一模塊進行交互時,此模塊利用屬性事件代理中的事件觸發器觸發一種特定類型的屬性事件;并將希望共享的數據通過屬性事件封裝后,加入到屬性事件池中。后繼的工作將與事件的發起者無關。被調用的模塊在屬性事件的觸發響應機制下,將能及時地得到被觸發事件的通知,并從相應的屬性事件中取得相關數據,同時啟動響應線程進行相應功能的執行。如果協同過程沒有完成,那么可以繼續觸發其他類型的屬性事件,繼續與其他模塊進行交互。由這么一組屬性事件,就完成了一組邏輯過程的設計。以屬性事件為中介搭建模塊間的協作橋梁。通過發起者與響應者的對應關系完成邏輯過程。利用屬性事件的輻射能力及響應模塊的監聽與響應機制,可以構造復雜的邏輯過程。每個屬性事件都有一個惟一的標志字段(或稱不事件名稱),這個標志是由系統開發人員根據需要指定。不同的屬性事件有不同的標志。某一模塊要處理某類屬性事件時,需要在屬性事件代理中進行注冊。其技術實現過程如圖2所示。
此項技術的優勢在于多線程、多模塊、群組方式的協同與通信。這種協同溝通參與的模塊或線程的數量很大時,軟件設計人員不必花費更多的時間去收集與維護某項邏輯有多少成員參與,只需要觸發某一屬性事件即可。后續的操作由每個相關的模塊自行內部處理。利用屬性事件構造了各功能模塊的外部接口及相互協同的邏輯流程。另外,屬性事件可以在任何時候、任何情況下根據系統設計的需要隨時觸發,并在事件觸發時,相關的數據也被一同提供,省略了數據獲取、維護等邏輯過程,降低了程序設計的工作量。
2實現過程
要實現屬性事件代理,需要實現允許其他模塊進行屬性監聽的注冊與取消注冊兩個接口。Java.bean包中的Property ̄ChangeSupport類簡化了這兩個接口的實現。通過這個類可以實例化屬性事件代理的事件觸發器。接口與事件觸發器的實現代碼如下:
a)屬性事件代碼的Java代碼實現
(a)構造事件觸發器對象與屬性事件池對象
private PropertyChangeSupport agent=new PropertyChangeSupport(this);
private Hashtable registedTable=new Hashtable();
//已經注冊的屬性事件
(b)實現屬性監聽的注冊與取消注冊接口
監聽注冊函數:
public void addPropertyChangeListener(String propertyName,Pro ̄pertyChangeListener listener){
agent.addPropertyChangeListener(propertyName,listener);
//注冊事件監聽
this.registedTable.put(propertyName,listener);
//添加到屬性事件池對象中
}
取消注冊函數:
public void removePropertyChangeListener(String propertyName,Pro ̄pertyChangeListener listener){
agent.removePropertyChangeListener(propertyName,listener);
//監聽取消
this.registedTable.remove(propertyName);
//從屬性事件池對象中清除此事件監聽
}
(c)構造觸發函數
/**
*2002年11月24日12:30PMby 戰洪飛
*用處:觸發屬性事件
*@param propertyName 觸發屬性事件的標志
*@param oldValue 觸發事件的現場數據
*@param newValue 觸發事件的現場數據
*/
public void fireMyPropertyChange(String propertyName,Object old ̄Value,Object newValue){
agent.firePropertyChange(propertyName,oldValue,newValue);
//啟動觸發器,并觸發事件
}
b)屬性事件發起過程的Java實現代碼
(a)準備現場數據,即構造oldValue與newValue集合對象(參數采用“名—值”對的方式存放)
private Hashtable oldValue=new Hashtable();//現在參數1
private Hashtable newValue=new Hashtable();//現在參數1
private void initPropertyParameters(){
oldValue.put(\"parameters1\",object1); //初始化現場參數1
……
newValue.put(\"parameter_a\",object_a);//初始化現場參數2
……
}
(b)定義屬性事件標注,并觸發屬性事件
public void firePropertyEvent(){
initPropertyParameters();//初始化事件參數
String propertyEventIDString=\"A New Property Event\";
//定義事件標志
eventAgent. fireMyPropertyChange(propertyEventIDString,oldValue,newValue);//觸發事件
}
c)屬性事件監聽與響應模塊的Java代碼實現
(a)啟動事件注冊
private void initPropertyEventRegister(){
String propertyEventIDString=\"A New Property Event\";
//定義屬性事件標志
eventAgent.addPropertyChangeListener(propertyEventIDString,this);//向屬性事件代理進行注冊
}
(b)實現響應函數
public void propertyChange(PropertyChangeEvent pcEvent){
String propertyEventIDString=pcEvent.getPropertyName();//取得接收到的屬性事件標志
if(property_name.equalsIgnoreCase(\"A New Property Event\")){//進行標志匹配
newValue =(Hashtable)pcEvent.getNewValue();//取得現場參數
System.out.println(\"A New Property Event was triggered\");//開發響應過程
……
}
}
3應用實例
下面以筆者開發的遠程屏幕共享系統為例,對基于屬性事件的協同技術的應用作簡要介紹。該系統的客戶端界面如圖3所示。該系統實現的主要功能是,任何一個客戶端的屏幕顯示都可以經過本系統實時地轉發到遠程的多個分散用戶的計算機上進行顯示,使每個用戶都看到相同的顯示結果與操作過程,進行異地的協同工作。例如異地產品協同設計、遠程協同醫療診斷等。它為企業內及企業間的協同交互合作提供了一個有益的輔助工具。
該系統要實現的邏輯比較簡單。首先客戶端程序要實時地檢測本地計算機顯示的屏幕變化,并將顯示結果通過socket發送回服務器端;服務器端根據接收到的信息,將顯示數據分發給服務器端的多個分發線程;再由分發線程通過socket通信,發布到其他用戶的客戶端計算機,還原計算機的顯示數據。因而每個用戶都看到了相同的顯示界面。
服務器端的關鍵是要維護當前有多少個用戶連接到服務器,并要將接收到的顯示數據分布到這些用戶的計算機。在線用戶的維護與管理及數據的分布相互關聯緊密,而且用戶狀態又是動態變化的,不適合集中管理。在此系統中使用屬性事件協同技術,通過屬性事件的觸發與響應機制實現在線用戶的自動維護與管理。
首先,當用戶連接到服務器后,服務器端會為每個用戶創建一個惟一的響應線程,負責與此客戶端代碼的通信。當響應線程創建時,線程便觸發了new user connected的屬性事件,在線用戶管理模塊便自動將用戶填加到列表,完成用戶的注冊。當用戶下線時,線程又觸發user quit的屬性事件,在線用戶管理模塊將清理此用戶,完成用戶的注銷工作。
同樣,當客戶端的屏幕顯示數據到達服務器端時,接收數據的線程觸發new screen arrived的屬性事件,服務器端的每個響應線程會自動接收此事件,并獨自將屏幕數據發送回各自的客戶端。處理的邏輯簡單、迅速。如果客戶端的數據只是想發送給遠程的某一指定用戶。那么服務器端也不必維護該用戶的信息,只需要在數據到達后觸發屬性事件update to administrator,那么就只有administrator對應的響應線程自動執行響應操作。程序設計員不必關心其他響應線程作何處理。
4結束語
本文介紹了Java socket編程中的模塊間協同溝通技術。基于屬性事件觸發與響應機制簡化了程序邏輯設計的復雜性,更便于進行模塊化設計及分布式的協作與響應。筆者利用此項技術在網絡系統程序中構建系統的信息神經,用以構造網格模型。
參考文獻:
[1]WEBER J L. Java 2編程詳解[M]. 卜照斌,段來盛,賴伶,等譯. 北京:電子工業出版社, 1999:843-866.
[2] WUTKA M. Java2企業版實用全書 [M]. 偉峰,等譯.北京:電子工業出版社, 2001:323-357.
[3] ECKEL B.Java編程思想[M]. 陳昊鵬,等譯. 北京:機械工業出版社, 2005:325-387.
[4] VANHELSUWE L.JavaBeans 從入門到精通[M]. 邱仲潘,等譯. 北京:電子工業出版社, 1998:30-291.
[5] 孫一林,彭波. Java網絡編程實例[M]. 北京:清華大學出版社,2003:112158.
“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”