設(shè)計(jì)模式在LWGUI的研究實(shí)現(xiàn)_第1頁(yè)
設(shè)計(jì)模式在LWGUI的研究實(shí)現(xiàn)_第2頁(yè)
設(shè)計(jì)模式在LWGUI的研究實(shí)現(xiàn)_第3頁(yè)
設(shè)計(jì)模式在LWGUI的研究實(shí)現(xiàn)_第4頁(yè)
設(shè)計(jì)模式在LWGUI的研究實(shí)現(xiàn)_第5頁(yè)
已閱讀5頁(yè),還剩7頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、設(shè)計(jì)模式課程論文題 目: 設(shè)計(jì)模式在LWGUI的實(shí)現(xiàn)研究 姓 名: 學(xué) 號(hào): 專 業(yè): 班 級(jí): 導(dǎo) 師: 摘要:設(shè)計(jì)模式的主要作用是適應(yīng)變化的需求,其靈活性可以使設(shè)計(jì)方案更容易擴(kuò)展和復(fù)用。在系統(tǒng)設(shè)計(jì)中,應(yīng)盡量使用成熟的設(shè)計(jì)模式來(lái)優(yōu)化設(shè)計(jì)模型的局部設(shè)計(jì)。本文以一個(gè)輕量級(jí)的跨平臺(tái)的圖形用戶界面的框架系統(tǒng)(Light Weight GUI,LWGUI)為例,詳細(xì)介紹了觀察者模式和外觀模式這兩種模式在LWGUI系統(tǒng)中的應(yīng)用實(shí)現(xiàn)。關(guān)鍵詞:設(shè)計(jì)模式;擴(kuò)展;復(fù)用;觀察者模式;外觀模式1引 言軟件復(fù)用是軟件開(kāi)發(fā)人員的不懈追求,它能夠提高軟件生產(chǎn)率以及軟件質(zhì)量。針對(duì)軟件復(fù)用,我們采用設(shè)計(jì)模式來(lái)記錄軟件設(shè)計(jì)知識(shí)

2、,這可以使軟件復(fù)用從代碼復(fù)用提高到軟件開(kāi)發(fā)各階段知識(shí)的復(fù)用。設(shè)計(jì)模式是可復(fù)用面向?qū)ο筌浖幕A(chǔ),它以系統(tǒng)化和規(guī)格化的方式記錄了可重復(fù)使用的軟件設(shè)計(jì)方案和經(jīng)驗(yàn)。它區(qū)分、命名并且抽象了面向?qū)ο笤O(shè)計(jì)中的通用概念。設(shè)計(jì)模式通過(guò)明確對(duì)象、對(duì)象間的協(xié)作和職責(zé)分配,捕捉到了隱藏在設(shè)計(jì)背后的意圖。2設(shè)計(jì)模式2.1觀察者模式 (1) 設(shè)計(jì)意圖 觀察者模式的設(shè)計(jì)意圖包括: 1) 定義對(duì)象之間多對(duì)一的依賴關(guān)系,也即多個(gè)對(duì)象依賴于一個(gè)對(duì)象的關(guān)系,同時(shí)保證,當(dāng)被依賴的對(duì)象狀態(tài)發(fā)生變化時(shí),所有的依賴者會(huì)被自動(dòng)地通知。觀察者模式的另一個(gè)名稱“出版訂閱模式”很好地說(shuō)明了這個(gè)設(shè)計(jì)意圖:被依賴的對(duì)象向外發(fā)布自己的狀態(tài),而此前訂閱

3、了該狀態(tài)的所有對(duì)象都會(huì)得到通知,這其實(shí)類似于一種消息在對(duì)象間的廣播。 2) 當(dāng)一個(gè)對(duì)象需要通知另外一個(gè)對(duì)象,而又無(wú)法預(yù)知哪些對(duì)象將被通知,通過(guò)觀察者模式就可以減弱通知對(duì)象和被通知對(duì)象之間的耦合關(guān)系。 3) 當(dāng)一個(gè)模塊(模塊A)的變化需要另一個(gè)模塊(模塊B)做出相應(yīng)的修改,而又不知道有多少個(gè)類會(huì)被修改時(shí),使用觀察者模式就可以切斷這種依賴關(guān)系,即模塊A的變化不再影響模塊B,模塊B也無(wú)需做任何修改。換句話說(shuō),這時(shí),模塊B對(duì)模塊A的依賴關(guān)系由直接依賴轉(zhuǎn)變?yōu)殚g接依賴,具體的依賴關(guān)系是由模塊A動(dòng)態(tài)設(shè)定的。因此,兩個(gè)模塊可以在互不干擾的情況系下,相對(duì)獨(dú)立地被復(fù)用和修改。 (2) 基本結(jié)構(gòu) 圖2-1為觀察者模

4、式的結(jié)構(gòu)圖。在結(jié)構(gòu)圖中,有如下一些類,它們共同完成觀察者模式的各項(xiàng)職責(zé)。 1) 主體(Subject)類:即被觀察者類的基類,它管理所有的觀察者,并提供添加和刪除觀察者的方法,觀察者的數(shù)量一般不受限制。 2) 觀察者(Observer)類:定義一個(gè)通知接口來(lái)接受主體類發(fā)來(lái)的通知消息。 3) 具體的主體(ConcreateSubject)類:即具體的被觀察者類,它針對(duì)不同的需求,實(shí)現(xiàn)具體的主體屬性和方法,決定何時(shí)發(fā)送通知消息等。 4) 具體的觀察者(ConcreateObserver)類:針對(duì)不同的需求,實(shí)現(xiàn)具體的通知接口,以接收具體的主體類發(fā)來(lái)的通知消息,并可以根據(jù)需要對(duì)消息進(jìn)行特定的處理。

5、圖2-1觀察者模式結(jié)構(gòu)圖2.2外觀模式 (1) 設(shè)計(jì)意圖 外觀模式可以為一個(gè)子系統(tǒng)中的多個(gè)類提供統(tǒng)一的接口。外觀模式定義了一個(gè)高層次的接口,并使一個(gè)子系統(tǒng)更易于使用。 (2) 基本結(jié)構(gòu) 圖2-2 為外觀模式的結(jié)構(gòu)圖。 圖2-2 外觀模式結(jié)構(gòu)圖 圖2-2中,子系統(tǒng)的接口不一定是具體的外觀類,它和外觀類之間的關(guān)系可能會(huì)有兩種: 1) 子系統(tǒng)的接口是一個(gè)抽象類,不包含任何屬性和具體實(shí)現(xiàn),其中定義的所有的接口函數(shù)都是純虛函數(shù);而外觀類是該抽象類的派生類,隱藏在子系統(tǒng)中。在這種實(shí)現(xiàn)方式中,客戶程序所看到的只是一個(gè)純粹的接口,而具體的實(shí)現(xiàn)都被外觀類封裝到了子系統(tǒng)內(nèi)部。 2) 子系統(tǒng)的接口就是外觀類的頭文件

6、(對(duì) C+語(yǔ)言而言),客戶程序可能會(huì)看到一些外觀類的私有屬性和私有方法。 顯然,第一種方法比較純粹,比較理論,而且,在第一種方法里,如果子系統(tǒng)的接口可以被多個(gè)子系統(tǒng)共用,它就會(huì)有多個(gè)不同的派生類,這在某些情況下非常有用。如果子系統(tǒng)的接口只有一個(gè)派生類,即該子系統(tǒng)的外觀類,可以使用第二種方法,因?yàn)樗容^簡(jiǎn)單和直接。 外觀類一般應(yīng)以單件類(Singleton)的形式出現(xiàn),這樣,客戶程序就可以通過(guò)單件類的靜態(tài)方法獲得子系統(tǒng)的惟一接口實(shí)例。另外,外觀類一般要負(fù)責(zé)創(chuàng)建和銷毀子系統(tǒng)中的其它相關(guān)對(duì)象,管理其它對(duì)象的生命周期。當(dāng)客戶程序調(diào)用外觀類中的接口函數(shù)時(shí),外觀類必須知道每一個(gè)特定的請(qǐng)求應(yīng)該發(fā)送給子系統(tǒng)中

7、的哪個(gè)類或?qū)ο?,或者,?yīng)該讓子系統(tǒng)中哪些類共同處理。 3觀察者模式在LWGUI系統(tǒng)中的應(yīng)用實(shí)現(xiàn) 根據(jù)對(duì) LWGUI 系統(tǒng)的架構(gòu)分析可知,在框架層和操作系統(tǒng)適配器層中,有幾個(gè)類和消息傳遞相關(guān),即操作系統(tǒng)適配器會(huì)在適當(dāng)?shù)臅r(shí)候,發(fā)送消息給應(yīng)用程序、屏幕、定時(shí)器管理器這三個(gè)類。但隨著系統(tǒng)不但的擴(kuò)展,消息的接收者數(shù)量,處理方式等都有可能在未來(lái)發(fā)生變化。在沒(méi)有引入觀察者模式前,系統(tǒng)的結(jié)構(gòu)圖如圖 3-1 所示。 圖3-1 未引入觀察者模式時(shí)的消息傳遞方案 LWG_OSAdaptor的派生類負(fù)責(zé)各具體操作系統(tǒng)的程序啟動(dòng)、主窗口創(chuàng)建、消息接收等工作。程序啟動(dòng)后,對(duì)于VxWork等操作系統(tǒng),該派生類可以通過(guò)一個(gè)循

8、環(huán)不斷查詢各種操作系統(tǒng)消息(如鍵盤、鼠標(biāo)、時(shí)鐘、網(wǎng)絡(luò)、串口等消息),對(duì)于Windows或Linux等操作系統(tǒng),可以在相應(yīng)的派生類中實(shí)現(xiàn)一個(gè)窗口函數(shù),以接受各種系統(tǒng)消息。 當(dāng)操作系統(tǒng)適配器類接收到系統(tǒng)消息后,它需要根據(jù)系統(tǒng)消息的類型,把消息發(fā)送給不同的對(duì)象,例如,鍵盤、鼠標(biāo)消息發(fā)送給屏幕類的對(duì)象實(shí)例,啟動(dòng)消息發(fā)送給應(yīng)用程序類的對(duì)象實(shí)例,時(shí)鐘消息發(fā)送給定時(shí)器管理器類的對(duì)象實(shí)例等等。顯然,此處的每一個(gè)消息都只是發(fā)給一個(gè)對(duì)象,并不會(huì)發(fā)送給多個(gè)觀察者,不存在一對(duì)多的依賴關(guān)系。 但隨著消息類型的不斷增多,接受消息的控制類在未來(lái)也可能會(huì)發(fā)生變化,而這種變化正好是觀察者模式試圖解決的問(wèn)題。而且,操作系統(tǒng)適配器

9、層要移植到不同的操作系統(tǒng)上,實(shí)際上存在多個(gè)不同的操作系統(tǒng)適配器層實(shí)例,所以,框架層的變化應(yīng)盡可能少地影響操作系統(tǒng)適配器層,否則,系統(tǒng)的擴(kuò)展性和復(fù)用性就無(wú)從談起,這同樣符合觀察者模式的設(shè)計(jì)意圖。因此,盡管這里不存在一對(duì)多的依賴關(guān)系,但為了達(dá)到減少層與層之間的耦合、把直接依賴變成間接依賴的目的,觀察者模式仍可發(fā)揮很大的作用。只是在具體實(shí)現(xiàn)上,LWGUI中的觀察者模式和標(biāo)準(zhǔn)的GoF的觀察者模式略有不同。 觀察者模式的實(shí)現(xiàn)方法如下:在LWGUI中,首先實(shí)現(xiàn)了一個(gè)Observer類,該類是一個(gè)抽象類,其中的 OSMessage()接口可用于接收操作系統(tǒng)消息,相當(dāng)于觀察者模式中的Update()方法。由于

10、該類會(huì)同時(shí)被框架層和操作系統(tǒng)適配器層使用,應(yīng)把它放在獨(dú)立的應(yīng)用包中。Observer類的代碼如下所示。 class LWG_OSMsgObserver public: virtual LWG_OSMsgObserver() virtual void OSMessage(LWG_Message * pMsg) = 0; ; 框架層的屏幕、應(yīng)用程序、定時(shí)器管理器等類都是從LWG_OSMsgObserver 類中繼承出來(lái)的,這樣它們都具有接收操作系統(tǒng)消息的能力。負(fù)責(zé)轉(zhuǎn)發(fā)操作系統(tǒng)消息的類是操作系統(tǒng)適配器層的適配器類LWG_OSAdaptor,但是,由于每種特定類型的消息不是發(fā)送給所有的觀察者,而是發(fā)送

11、給某一個(gè)注冊(cè)了該類型消息的接收者,因此,記錄觀察者的方式和標(biāo)準(zhǔn)的觀察者模式略有不同。 先定義消息類型的枚舉結(jié)構(gòu): enum LWG_MSG_TYPE LWG_MSG_STARTUP, /系統(tǒng)啟動(dòng)消息 LWG_MSG_HALT, /系統(tǒng)停止消息 LWG_MSG_DRAW, /屏幕刷新或窗口元素重畫消息 LWG_MSG_KEY, /鍵盤消息 LWG_MSG_MOUSE, /鼠標(biāo)消息 LWG_MSG_TIMER, /定時(shí)器消息 /以上為所有的系統(tǒng)消息 /系統(tǒng)內(nèi)部使用,不是一個(gè)消息類型,表示最大的系統(tǒng)消息個(gè)數(shù), /之前為所有的系統(tǒng)消息,之后為內(nèi)部消息 LWG_MAX_SYS_MSG, /請(qǐng)求重畫消息,

12、控件需要重畫時(shí)向窗口發(fā)送此消息,/窗口需要重畫時(shí)向屏幕發(fā)送此消息,/由屏幕根據(jù)該窗口是否是焦點(diǎn)窗口來(lái)決定如何重畫LWG_MSG_DRAW_REQUEST,LWG_MSG_FOCUS, /焦點(diǎn)切換消息LWG_MSG_NOTIFY, /通知消息LWG_MSG_UPDATE_VIEW / MVC模式的視圖更新消息;對(duì)于每一類系統(tǒng)消息,需要記錄一個(gè)接收該消息的觀察者,而且,在 LWGUI 系統(tǒng)中,每一類消息只能有一個(gè)觀察者(當(dāng)然,同一個(gè)觀察者可以觀察多個(gè)類消息),因此,只需在LWG_OSAdaptor類中定義一個(gè)大小為L(zhǎng)WG_MAX_SYS_MSG 的數(shù)組,用該數(shù)組來(lái)保存每個(gè)消息類型對(duì)應(yīng)的觀察者對(duì)象指

13、針即可。觀察者注冊(cè)時(shí),需要提供它想注冊(cè)的消息類型,然后該觀察者的指針就會(huì)被記錄在數(shù)組的相應(yīng)位置。當(dāng)然,注冊(cè)的前提是該觀察者類實(shí)現(xiàn)了LWG_OSMsgObserver接口。當(dāng)LWG_OSAdaptor類接收到系統(tǒng)消息時(shí),只要從數(shù)組中查詢出該系統(tǒng)消息對(duì)應(yīng)的觀察者對(duì)象指針,然后調(diào)用該指針的OSMessage()方法,就可以把消息發(fā)送給觀察者來(lái)。LWG_OSAdaptor 類和觀察者模式的相關(guān)代碼如下:class LWG_OSAdaptorpublic:/* 注冊(cè)系統(tǒng)消息的觀察者* 每個(gè)系統(tǒng)消息只能有一個(gè)觀察者(即消息接受者,LWG_OSMsgObserver的子類)* type 系統(tǒng)消息類型* pO

14、bserver注冊(cè)的系統(tǒng)消息的觀察者指針* 該消息以前設(shè)置的觀察者指針*/LWG_OSMsgObserver * SetMsgObserver(const WORD type, LWG_OSMsgObserver * constpObserver);/* 發(fā)送系統(tǒng)消息給注冊(cè)的觀察者* pMsg 指向要發(fā)送的系統(tǒng)消息,由于是同步消息,發(fā)送者必須負(fù)責(zé)分配和釋放該消息*/void SendMsg(LWG_Message * pMsg);protected:/ 記錄所有的系統(tǒng)消息的觀察者的數(shù)組 LWG_OSMsgObserver * m_ppObserverLWG_MAX_SYS_MSG; ; LWG

15、_OSMsgObserver * LWG_OSAdaptor:SetMsgObserver(const WORD type, LWG_OSMsgObserver * const pObserver) LWG_OSMsgObserver * tmp = m_ppObservertype; m_ppObservertype = pObserver; return tmp; void LWG_OSAdaptor:SendMsg(LWG_Message * pMsg) if(pMsg-wTypewType) m_ppObserverpMsg-wType-OSMessage(pMsg); 最終的框架層和

16、操作系統(tǒng)適配器層之間的關(guān)系如圖 3-2 所示。 圖3-2 引入觀察者模式后的消息傳遞方案 4外觀模式在LWGUI中的應(yīng)用實(shí)現(xiàn) LWGUI的適配器子系統(tǒng)很簡(jiǎn)單,只包含兩個(gè)分析類。其中,LWG_OSAdaptor 類負(fù)責(zé)LWGUI系統(tǒng)的啟動(dòng)和操作系統(tǒng)消息的轉(zhuǎn)發(fā),LWG_OSDrawInterface類負(fù)責(zé)將繪圖調(diào)用轉(zhuǎn)發(fā)給特定操作系統(tǒng)中的繪圖接口。 由于LWGUI需要移植到不同的操作系統(tǒng),如果把操作系統(tǒng)相關(guān)的代碼實(shí)現(xiàn)在LWG_OSAdaptor類和LWG_OSDrawInterface類中,則必須為每個(gè)操作系統(tǒng)準(zhǔn)備一個(gè)適配器類和繪圖接口類。編譯的時(shí)候,只需把相應(yīng)操作系統(tǒng)的適配器類和繪圖接口類連接到框

17、架系統(tǒng)即可。這種方法雖然可行,但存在一些問(wèn)題,例如,為了保證代碼的一致性,不同操作系統(tǒng)的相關(guān)代碼必須擁有相同的文件名和類名,編碼時(shí)只能將它們放在不同的目錄中,這種做法顯然會(huì)給以后的管理和維護(hù)帶來(lái)很大的麻煩。 適應(yīng)不同需求,同時(shí)支持多種環(huán)境,是GoF設(shè)計(jì)模式的強(qiáng)項(xiàng)。對(duì)于上面提到的適應(yīng)不同操作系統(tǒng)的問(wèn)題,需把LWG_OSAdaptor、LWG_OSDrawInterface 類實(shí)現(xiàn)為抽象類,即二者看作純粹的接口,然后,對(duì)每種具體的操作系統(tǒng),都從LWG_OSAdaptor類和LWG_OSDrawInterface類中繼承出特定的派生類,將只與具體操作系統(tǒng)的屬性和方法實(shí)現(xiàn)在派生類中即可。 在Windo

18、ws系統(tǒng)可生成LWG_Win32Adaptor和LWG_Win32DrawInterface 這兩個(gè)派生類。在Unix、Linux等支持X11圖形環(huán)境的系統(tǒng)中,可以生成 LWG_X11Adaptor和LWG_X11DrawInterface這兩個(gè)派生類。 外觀模式的實(shí)現(xiàn)方法如下:由上面可知,對(duì)于一個(gè)具體的操作系統(tǒng)平臺(tái),LWGUI適配器子系統(tǒng)只需四個(gè)類(兩個(gè)抽象類和兩個(gè)派生類)就可以實(shí)現(xiàn)所有功能了。為了讓這個(gè)子系統(tǒng)有一個(gè)外部類可見(jiàn)的、統(tǒng)一的接口,是否有必要再添加一個(gè)外觀類呢? 如果添加一個(gè)外觀類,則它的職責(zé)就是把框架層對(duì)適配器子系統(tǒng)的調(diào)用請(qǐng)求發(fā)送給具體的操作系統(tǒng)適配器類或具體的繪圖接口類,然后再

19、由后者進(jìn)一步將調(diào)用轉(zhuǎn)發(fā)給操作系統(tǒng)或底層繪圖接口。這個(gè)外觀類的職責(zé)并不很多,完全可以合并到其他類中。因此,可以由適配器類LWG_OSAdaptor來(lái)承擔(dān)外觀類的職責(zé),而 LWG_OSAdaptor類的頭文件可以作為整個(gè)適配器子系統(tǒng)的接口直接輸出??蚣軐拥目蛻舫绦蛲ㄟ^(guò)LWG_OSAdaptor類來(lái)訪問(wèn)整個(gè)適配器子系統(tǒng)的功能。一般而言,LWG_OSAdaptor類必須是一個(gè)單件類,客戶程序可以通過(guò)單件類的靜態(tài)方法來(lái)訪問(wèn)外觀類的各項(xiàng)功能。此外,LWG_OSAdaptor類必須負(fù)責(zé)創(chuàng)建和刪除繪圖接口類,并能把相關(guān)的調(diào)用發(fā)給繪圖接口類。圖4-1 顯示了在 Win32 環(huán)境下適配器子系統(tǒng)中外觀類。圖4-1

20、Win32 環(huán)境下適配器子系統(tǒng)的類圖 在LWG_OSAdaptor類只能包含一個(gè)指向LWG_OSDrawInterface類的指針,而具體創(chuàng)建繪圖接口類的任務(wù),則應(yīng)交給LWG_OSAdaptor類的派生類來(lái)完成。下面的代碼顯示了在Win32系統(tǒng)中,當(dāng)程序啟動(dòng)時(shí),Win32的適配器類LWG_Win32Adaptor負(fù)責(zé)創(chuàng)建Win32的繪圖接口類LWG_Win32DrawInterface的過(guò)程。 bool LWG_Win32Adaptor:InitInstance() if (! m_pDraw) m_pDraw = new LWG_Win32DrawInterface(); 由于LWG_OSAdaptor類是一個(gè)外觀類,客戶程序的所有調(diào)用都必須通過(guò)它傳入子系統(tǒng),必須在LWG_OSAdaptor類中把繪圖接口中的所有繪圖函數(shù)重新定義一遍。當(dāng)客戶程序調(diào)用這些繪圖接口時(shí),LWG_OSAdaptor類就可以通過(guò)指向 LWG_OSDrawInterface類的指針,直接調(diào)用具體的繪圖接口

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論