閒談組合模式 基於UI動畫框架

2021-08-21 13:36:42 字數 3399 閱讀 7736

先來看下組合模式的定義:

將物件組合成樹型結構以表示「部分 - 整體」的層次結構。組合模式使得使用者對單個物件和組合物件的使用具有一致性。

這個定義看起來舒服一點。再看一下類圖:

組合模式的關鍵是抽象乙個類,既可以表示葉子物件,又可以表示組合物件,所以葉子物件和組合物件都要從統一的介面類派生,這樣客戶**就可以用同樣的方法訪問葉子物件和組合物件,而不用區分葉子物件和組合物件。component介面提供典型的幾種操作:

這幾個操作對組合物件類是有意義的,因為組合物件持有葉子物件或組合物件(遞迴)的集合;但對於葉子物件類沒什麼意義,因此葉子物件中,這幾個介面通常都是空操作,或者輸出錯誤日誌,或者丟擲異常。

通常,組合模式會組合出樹型結構來,將多個元件物件自然地形成了物件樹。因為組合物件還可以繼續包含組合物件(陣列),因此形成了遞迴關聯,客戶的**在實現中不可避免的會出現遞迴呼叫的**結構。因為要向客戶**提供統一的操作,因此抽象介面類中的介面是既支援葉子節點,又支援組合節點的介面的大雜燴。有一種安全的實現是將有關組合物件的介面放到composite物件類中,那麼客戶**就不太可能針對葉子節點呼叫這些介面,但是這樣以來,客戶**就需要區分葉子物件和組合物件了。

有時候,component中需要提供乙個介面:isleaf或者iscomposite,供客戶**判斷是葉子物件還是組合物件。通常來說,組合模式假設客戶**不需要知道這個資訊,但有的應用場景確實有這種需要,假如物件樹需要以圖形的方式顯示出來,而顯示層邏輯在其它語言中(比如lua)實現,這些語言不支援物件導向程式設計模型,那就有很多地方需要知道具體的物件是葉子還是組合節點了,比如右鍵選單:葉子節點的右鍵選單和組合節點的右鍵選單不一樣(這個很正常),或者兩者的圖示不一樣。

組合模式中,乙個節點自帶到子節點的引用,在有些場合,可能有需要回溯到父節點,因此可以在實現中增加乙個到父節點物件的引用(還是component型別)。

組合模式,相對來說是乙個比較容易理解的設計模式,大家每天接觸到的電腦上的「資料夾-檔案」結構,幾乎和組合模式的結構完美對應。在前面直譯器的兩篇文章中,大家已經看到了動畫框架中有兩個符合組合模式的結構,下面分別進行討論。

先看下動畫類的結構圖:

動畫組由單個動畫或動畫組構成,對於客戶**來說,操縱動畫組和操縱單個動畫並沒什麼區別,都是在操縱乙個animation物件,而動畫組的結構又是樹形結構,因此組合模式是天然的選擇。

groupanimation從animation介面類派生,因此動畫組對客戶**來說,就像動畫一樣;同時groupanimation又包含有單個動畫或者動畫組,因為singleanimation也是從animation類派生,所以,groupanimation只需持有到animation介面類的(多個)引用;這種「既從animation派生又持有到animation控制代碼的引用」的遞迴巢狀結構,就自然地構成了樹形結構。

groupanimation要再實現addanimation介面,才能構建樹形結構:

void groupanimation::

addanimation

(animation* animation)

groupanimation是樹形結構,因此如果需要操作樹上的某乙個物件,需要以乙個索引序列在樹上定位出目標物件(索引序列實際上是目標物件在樹上的每一層枝杈的索引組合),比如要設定乙個animation中某個strategy的引數:

bool groupanimation::

setstrategyparm

(vector<

int>

& ids,

const string& parm)

bool singleanimation::

setstrategyparm

(vector<

int>

& ids,

const string& parm)

bool strategys::

setstrategyparm

(vector<

int>

& ids,

const string& parm)

bool framestrategy::

setpolicyparm

(vector<

int>

& ids,

const string& parm)

return

true

;}

groupanimation封裝了組合節點,動畫框架中有兩種groupanimation:groupanimationserial(序列動畫組)和groupanimationparallel(並行動畫組)。這兩者都從groupanimation派生:

這兩者最明顯的不同就是啟動方式:

// 序列動畫組

bool groupanimationserial::

run(

void

)// 並行動畫組

bool groupanimationparallel::

run(

void

)

動畫框架中,動畫策略也是乙個樹形結構,策略組是由單個策略或策略組構成:

對於客戶**來說,它只持有乙個istrategy的控制代碼,並不關心是單個策略還是策略組,只要完成指定的動畫即可;因此組合模式又是乙個很自然的選擇。

strategys也從istrategy介面類繼承,並持有到istrategy控制代碼的引用(多個),同時實現了addstrategy介面:

void strategys::

addstrategy

(istrategy* strategy)

框架中也有兩種strategys:strategysserial(序列策略組)和strategysparallel(並行策略組),這兩者都從istrategy派生:

這兩者最明顯的不同就是執行方式。具體**可以參見前文的strategys章節。

組合模式是相對比較容易理解的模式,在需要用到該模式的地方,都是相當自然的需求,一般都具有以下兩個特色:

因此,不用刻意設計,組合模式就是你的自然選擇。

閒談設計模式

設計模式 design pattern 是一套被反覆使用 多數人知曉的 經過分類的 設計經驗的總結。了解這些前輩們總結出來的經驗有助於幫助你寫出來更優秀的 幫助你寫出可擴充套件 可讀 可維護的高質量 在極客時間裡推出了資料結構和設計模式的王爭說了一句話,如果說 資料結構與演算法之美 是教你寫出高效的...

組合模式 設計模式 組合模式

1.需求分析 假設要給乙個大公司做辦公管理系統,公司有人力資源部 財務部等,然後公司在其他城市還有分公司,分公司也有自己的人力資源部 財務部等,要求總公司 分公司以及各部分成樹狀結構管理。要完成這麼乙個系統,為了有乙個更好的設計,方便開發的展開,就需要了解乙個設計模式 組合模式。2.定義 將物件組合...

設計模式 組合模式 組合模式使用

目錄 組合模式概括 組合模式使用場景 定義 將物件組合成樹形結構以表示 部分 整體 的層次結構 作用 使客戶端對單個物件和組合物件保持一致的處理方式 使用場景 1.希望客戶端可以忽略組合物件與單個物件的差異時 2.處理乙個樹形結構時 優點 清楚的定義分層次的複雜物件,表示物件的全部或部分層次 讓客戶...