深入理解設計模式(21) 組合模式

2022-05-26 15:48:09 字數 3793 閱讀 3882

定義:將物件以樹形結構組織起來,以達成「部分-整體」的層次結構,使得客戶端對單個物件和組合物件的使用具有一致性。

動機(motivation)

客戶**過多地依賴於物件容器複雜的內部實現結構,物件容器內部實現結構(而非抽象介面)的變化將引起客戶**的頻繁變化,帶來了**的維護性、擴充套件性等弊端。

如何將「客戶**與複雜的物件容器結構」解耦?讓物件容器自己來實現自身的複雜結構,從而使得客戶**就像處理簡單物件一樣來處理複雜的物件容器?

意圖(intent)

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

組合模式,現在學習就是虛類繼承虛類,然後增加虛方法。最終實類繼承第二個虛類,重寫所有虛方法。

結構圖說明:

(1)component:組合中的物件宣告介面,在適當情況下實現所有類共有的預設行為,宣告乙個介面用於訪問和管理component的子元件。在遞迴結構中定義乙個介面,用於訪問乙個父部件,並在合適的情況下實現它。(可選)

(2)leaf:在組合中表示葉節點,葉節點沒有子節點,定義物件的基本行為。

(3)composite:定義有子部件的那些部件的行為,儲存子部件並在component介面實現與子部件有關的操作。

(4)client:通過component介面操作組合部件的物件。

1.需求重要體現部分與整體的層次結構時

2.你希望使用者忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。

優點

1.使客戶端呼叫簡單,客戶端可以一致的使用組合結構或其中單個物件,使用者就不必關係自己處理的是單個物件還是整個組合結構,這就簡化了客戶端**。

2.更容易在組合體內加入物件部件. 客戶端不必因為加入了新的物件部件而更改**。

缺點

組合模式不容易限制組合中的構件。

組合模式有兩種實現方式,一種是:透明式的組合模式,另外一種是:安全式的組合模式。在這裡我就詳細說一下何為「透明式」,何為「安全式」。所謂透明式是指「抽象構件角色」定義的介面行為集合包含兩個部分,一部分是葉子物件本身所包含的行為(比如operation),另外一部分是容器物件本身所包含的管理子物件的行為(add,remove)。這個抽象構件必須同時包含這兩類物件所有的行為,客戶端**才會透明的使用,無論呼叫容器物件還是葉子物件,介面方法都是一樣的,這就是透明,針對客戶端**的透明,但是也有他自己的問題,葉子物件不會包含自己的子物件,為什麼要有add,remove等類似方法呢,呼叫葉子物件這樣的方法可能(注意:我這裡說的是可能,因為有些人會把這些方法實現為空,不做任何動作,當然也不會有異常丟擲了,不要抬槓)會丟擲異常,這樣就不安全了,然後人們就提出了「安全式的組合模式」。所謂安全式是指「抽象構件角色」只定義葉子物件的方法,確切的說這個抽象構件只定義兩類物件共有的行為,然後容器物件的方法定義在「樹枝構件角色」上,這樣葉子物件有葉子物件的方法,容器物件有容器物件的方法,這樣責任很明確,當然呼叫肯定不會丟擲異常了。大家可以根據自己的情況自行選擇是實現為「透視式」還是「安全式」的,以下我們會針對這兩種情況都有實現,具體實現如下:

namespace

透明式的組合模式的實現

//////

該word文件類就是葉子構件的定義,該型別就相當於是leaf型別,不能在包含子物件

/// public

sealed

class

word : folder

//刪除資料夾或者檔案

public

override

void

remove(folder folder)

//開啟檔案--該操作相當於component型別的operation方法

public

override

void

open()

}//////

sonfolder型別就是樹枝構件,由於我們使用的是「透明式」,所以add,remove都是從folder型別繼承下來的

/// public

class

sonfolder : folder

//刪除資料夾或者檔案

public

override

void

remove(folder folder)

//開啟資料夾--該操作相當於component型別的operation方法

public

override

void

open()

}public

class

program}}

以上**就是「透明式的組合模式」實現,以下**就是「安全式的組合模式」實現:

namespace

安全式的組合模式的實現

//////

該word文件類就是葉子構件的定義,該型別就相當於是leaf型別,不能在包含子物件

/// public

sealed

class word : folder //

這型別現在很乾淨

}//////

sonfolder型別就是樹枝構件,現在由於我們使用的是「安全式」,所以add,remove都是從此處開始定義的

/// public

abstract

class sonfolder : folder //

這裡可以是抽象介面,可以自己根據自己的情況而定

}//////

nextfolder型別就是樹枝構件的實現類

/// public

sealed

class

nextfolder : sonfolder

//刪除資料夾或者檔案

public

override

void

remove(folder folder)

//開啟資料夾--該操作相當於component型別的operation方法

public

override

void

open()

}public

class

program}}

asp.net中的panel物件就是乙個composite物件,而button物件就是leaf物件。button和panel都繼承自system.web.ui.control類。它實際上是在panel裡面加了乙個controls屬性,然後controls屬性是乙個集合屬性,它有add和remove方法。

在asp.net中就是這樣,每乙個控制項都有controls屬性,也就是說每個控制項都是一種容器控制項(除了literalcontrol)。這種方式把我們對安全性的擔憂,統統放到容器(即asp.net中的controls)中去處理。

這個模式在.net 中最典型的應用就是應用與winforms和web的開發中,在.net類庫中,都為這兩個平台提供了很多現有的控制項,然而system.windows.forms.dll中system.windows.forms.control類就應用了組合模式,因為控制項包括label、textbox等這樣的簡單控制項,這些控制項可以理解為葉子物件,同時也包括groupbox、datagrid這樣復合的控制項或者叫容器控制項,每個控制項都需要呼叫onpaint方法來進行控制項顯示,為了表示這種物件之間整體與部分的層次結構,微軟把control類的實現應用了組合模式(確切地說應用了透明式的組合模式)。

深入理解23種設計模式 8 組合模式

組合模式 composite pattern 又叫部分整體模式,是用於把一組相似的物件當作乙個單位的物件。組合模式依據樹形結構來組合物件,用來表示部分以及整體層次。這種型別的設計模式屬於結構型模式,它建立來物件組的樹形結構。需求 展示乙個學校有多少個學校院系組成,乙個學院有多少個學院,乙個學院有多個...

設計模式原則21 組合模式

將物件組合成樹形結構以表示 部分 整體 的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。1 component 抽象構件角色 定義參加組合物件的共有方法和屬性,可以定義一些預設的行為或屬性。2 leaf 葉子構件 葉子物件,其下再也沒有其他的分支,也就是遍歷的最小單位。3 composi...

深入理解23種設計模式 21 狀態模式

狀態模式 state pattern 它主要是用來解決物件在多種狀態之間的轉換,需要對外輸出不同的行為的問題,狀態和行為是一一對應的,狀態之間可以互相轉換。當乙個物件的內在狀態改變時,允許改變其行為,這個物件看起來是改變了其他類。活動 假如每參加一次這個活動要扣除50積分,中獎概率是10 獎品數量固...