C++設計模式第四講_第1頁
C++設計模式第四講_第2頁
C++設計模式第四講_第3頁
C++設計模式第四講_第4頁
C++設計模式第四講_第5頁
已閱讀5頁,還剩31頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、C+設計模式教程第四講:UIPLib設計模式(一) (組合模式、迭代器模式、策略模式、適配器模式、裝飾模式)主講人:步磊峰 UIPower 3D界面引擎負責人前言: 2 在前面三講中,我們詳細講解了創建模式。由于創建模式相對來說功能比較單一,而結構模式和行為模式涉及到軟件架構以及對象間通信關系。為了更好的演示相關設計模式,特意編寫了UIPLib以及基于UIPLib上的UIPPaint應用程序來演示涉及到的相關行為和結構模式: UIPLib用到的模式: 已講解過的模式: 單例模式(CApplication) 工廠模式(渲染系統) 將要講解的模式: 組合模式(控件系統) 迭代器模式(CArrayI

2、terator,節點迭代器) 策略、裝修、適配模式(節點迭代器) 觀察者模式(事件系統) 模板方法模式 UIPaint用到的模式: 將要講解的模式: 中間者模式(UIPLib和UIPPaint的紐帶) 狀態模式 (各種圖元的切換) 命令模式 (實現Undo(Ctrl-Z)/Redo(Ctrl-Y)功能) 訪問者模式 (圖元的繪制) 職責鏈模式 (F1幫助系統)第一節: 組合模式(控件系統)3意圖: 將對象組合成樹形結構以表示“部分-整體”的層次結構。Composite使用戶對單個對象和組合對象的使用具有一致 性。 由意圖描述可知,組合就是對象的集合,其中一個對象既可以是一個組合,也可以是一個簡

3、單的、單一的對象。 很符合樹的數據結構模式。 在整篇教程中,我們將樹結構等同于組合模式,具有互換性。 在樹的術語中,對象可以使帶有其他分支的節點,也可以是葉子。 第一節: 組合模式(控件系統)4開發中的存在的問題: 在實際開發中遇到的問題是:對于組合中的所有對象都要求具有一個簡單的,單一的訪問接口并要求能區分節點和葉 子 ,這兩者是矛盾的。節點可以由孩子并允許添加孩子。而葉子節點不允許有孩子,也不允許添加孩子。 當我們要區分葉子和節點時,可能使用的一種結構方式: struct ICompositeBase virtual ICompositeBase* GetParent() = 0; vir

4、tual ICompositeBase* GetRoot() = 0; virtual bool IsLeaf() const () = 0; ; struct CLeaf : public ICompositeBase virtual ICompositeBase* GetParent(); virtual ICompositeBase* GetRoot(); virtual bool IsLeaf() const return true; ; struct CNode : public ICompositeBase virtual ICompositeBase* GetParent();

5、virtual ICompositeBase* GetRoot(); virtual bool IsLeaf () const return false; virtual bool AddChild( ICompositeBase* c); virtual bool RemoveChild(int idx); virtual vector GetChildren(); ;第一節: 組合模式(控件系統)5 在這種區分葉子和節點的組合模式中,存在兩個問題: 1) 葉子和節點雖然都是ICompositeBase的子類,但是CNode對ICompositeBase進行了接口函數的添加。這意味著當 我們

6、 要進行樹遍歷的時候,需要判斷是否是CNode節點,如果是,要將ICompositeBase指針強轉成CNode指針, 然后進行CNode的相關操作,它違反了”Composite使用戶對單個對象和組合對象的使用具有一致性“的意圖。2) 區分葉子和節點的組合模式,導致葉子不能添加兒子。如果一個職位升職系統中,小職員使用葉子表示,那么他永遠 都只能當小職員,永遠沒法升職到團隊領導。剝奪了小職員奮斗的目標。 第一節: 組合模式(控件系統)6開發中的存在的問題: 在實際開發中遇到的問題是:對于組合中的所有對象都要求具有一個簡單的,單一的訪問接口并要求能區分節點和葉 子 ,這兩者是矛盾的。節點可以由孩子

7、并允許添加孩子。而葉子節點不允許有孩子,也不允許添加孩子。 當我們要區分葉子和節點時,可能使用的另外一種結構方式: struct ICompositeBase virtual ICompositeBase* GetParent() ; virtual ICompositeBase* GetRoot(); virtual bool IsLeaf() const () return true; virtual bool AddChild( ICompositeBase* c); virtual bool RemoveChild(int idx); virtual vector GetChildre

8、n(); ; struct CNode : public ICompositeBase virtual bool IsLeaf() const () return false;struct CLeaf : public ICompositeBase /拋出異常 virtual bool AddChild( ICompositeBase* c); /拋出異常 virtual bool RemoveChild(int idx); /返回的vector.size() 必須等于0 virtual vector GetChildren(); ; 第一節: 組合模式(控件系統)7 在這種區分葉子和節點的組

9、合模式中: 1) 葉子和節點都是ICompositeBase的子類,具有一致的接口函數。這意味著當我們 要進行樹遍歷的時候,不需要判斷 是否是CNode節點還是CLeaf節點,也不需要強制轉換了。很符合我們的意圖”Composite使用戶對單個對象和組合 對象的使用具有一致性“的意圖。2) 區分葉子和節點的組合模式,導致葉子不能添加兒子。如果一個職位升職系統中,小職員使用葉子表示,那么他永遠 都只能當小職員,永遠沒法升職到團隊領導。剝奪了小職員奮斗的目標。3) 如果仍舊使用職位升值系統,并且允許小職員也能夠升職的話,我們只需要讓小職員繼承自CNode,并且其兒子節點 數組為空,這種情況下就可以

10、進行升職了。由此可見,區分葉子和節點或者更進一步,我們不區分葉子還是節點,都可以看成是組合模式。我們的控件系統使用的是不區分葉子和節點的模式。即使某個節點無兒子,也可在運行時添加兒子節點。 第一節: 組合模式(控件系統)8 UIPLib中的組合模式中類的繼承關系: 第一節: 組合模式(控件系統)91、class CNode類:基類,代表一個組合模式。定義了一系列接口方法。2、template class CTypeNode : public CNode 模板類,繼承自CNode,該類必須被繼承。3、class CControlBase : public CTypeNode 我們從CTypedN

11、ode繼承。由于在CTypeNode中,我們實現了所有模板化的操作。 例如 所有返回CNode*的函數,由于CTypedNode經過override,都會返回CControlBase*,這樣更加具有通用性。 所有的控件都可以繼承自CControlBase類,進行擴展。例如CButton,CCombox等都可以繼承自CControlBase。4、class CControlManager : public CControlBase 組合(或樹)結構的根節點。程序入口類CApplication持有一個CControlManager類的指針,代表根節點。 第二節: 組合模式(控件系統)實現要點101

12、、樹節點析構: 它必須是深度優先,后根遍歷的遞歸析構過程。 第二節: 組合模式(控件系統)實現要點112、區分Remove和Detach操作: 第二節: 組合模式(控件系統)實現要點123、節點添加時要注意防止循環引用以及保證父親的唯一性: 第三節: 在控件系統中使用組合模式的優點13 第三節: 在控件系統中使用組合模式的優點14優點: 1、我們可以在運行時任意添加或刪除子節點,從而形成復雜的節點樹。2、控件的組合層次樹蘊含天然的深度遮擋關系,在渲染和碰撞檢測時需要這種深度遮擋關系。 第三節: 在控件系統中使用組合模式的優點15優點: 3、很容易進行坐標系統的變換。在我們的控件體系中,在設置位

13、置時候,使用相對于父控件偏移的局部坐標系統。 而我們的碰撞檢測以及局部刷新使用的是基于ClientRect的全局坐標系統,而使用組合層次關系,我們可以非常容易進行局部-全局以及全局-局部坐標的轉換: 第三節: 在控件系統中使用組合模式的優點16 第三節: 在控件系統中使用組合模式的優點17優點: 4、有利于控件父子之間的裁剪(Clip),既子控件的尺寸如果超過父控件的尺寸,那么子控件超過部分必須被裁剪掉。 第四節:迭代器模式18在前面的組合模式中,我們使用的都是遞歸方式對組合模式進行遍歷。事實上,我們可以使用迭代器方式獲得同樣的效果,并且避免了遞歸調用。那么我們來看一下如何實現迭代器: 第五節

14、:迭代器+策略模式19迭代器意圖:提供一種方法順序訪問聚合對象中各個元素,而又不需暴露該對象的內部表示。我們前面定義了一個迭代器模板接口。我們會發現對于一個線性存儲的容器來說,有兩種迭代順序: 既 從左到右的迭代順序 從右到左的迭代順序我們有兩種實現方式進行解決: 1)定義兩個迭代器,如果std容器中一樣,正向迭代器,反向迭代器。 2)使用策略模式,以模板參數傳入。我們使用第二種方式實現。 第五節:迭代器+策略模式20策略模式意圖:定義一系列的算法,將他們一個個封裝起來,并且使他們可以相互替換。本模式使得算法可獨立于使用 它的客戶而變化。 第六節:ArrayIterator實現21 第七節:組合(樹節點)迭代+策略+裝飾+適配模式22裝飾模式意圖:動態的給一個對象添加一些額外的職責,裝修模式相比生成子類來說更靈活。適配器模式意圖:將一個類的接口轉換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的哪些類 可以一起工作。 第七節:組合(樹節點)迭代+策略+裝飾+適配模式23 第七節:組合(樹節點)迭代+策略+裝飾+適配模式24 第七節:組合(樹節點)迭代+策略+裝飾+適配模式25 第七節:組合(樹節點)迭代+策略+裝飾+適配模式26 第七節:組合(樹節點)迭代+策略+裝飾+適配模式27 第八節:組合(樹節點)先根迭代器的實現28 第九節:組

溫馨提示

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

評論

0/150

提交評論