問題描述
上圖,是乙個公司的組織結構圖,總部下面有多個子公司,同時總部也有各個部門,子公司下面有多個部門。如果對這樣的公司開發乙個oa系統,作為程式設計師的你,如何設計這個oa系統呢?先不說如何設計實現,接著往下看,看完了下面的內容,再回過頭來想怎麼設計這樣的oa系統。
什麼是組合模式?
在gof的《設計模式:可復用物件導向軟體的基礎》一書中對組合模式是這樣說的:將物件組合成樹形結構以表示「部分-整體」的層次結構。組合(composite)模式使得使用者對單個物件和組合物件的使用具有一致性。
組合模式(composite)將小物件組合成樹形結構,使使用者操作組合物件如同操作乙個單個物件。組合模式定義了「部分-整體」的層次結構,基本物件可以被組合成更大的物件,而且這種操作是可重複的,不斷重複下去就可以得到乙個非常大的組合物件,但這些組合物件與基本物件擁有相同的介面,因而組合是透明的,用法完全一致。
我們這樣來簡單的理解組合模式,組合模式就是把一些現有的物件或者元素,經過組合後組成新的物件,新的物件提供內部方法,可以讓我們很方便的完成這些元素或者內部物件的訪問和操作。我們也可以把組合物件理解成乙個容器,容器提供各種訪問其內部物件或者元素的api,我們只需要使用這些方法就可以操作它了。
uml類圖
component:
為組合中的物件宣告介面;
在適當的情況下,實現所有類共有介面的預設行為;
宣告乙個介面用於訪問和管理component的子元件。
leaf:
在組合中表示葉節點物件,葉節點沒有子節點;
在組合中定義葉節點的行為。
composite:
定義有子部件的那些部件的行為;
儲存子部件。
client:
通過component介面操作組合部件的物件。
**實現
/*
** filename : compositepatterndemo
** author : jelly young
** date : 2013/12/09
** description : more information, please go to
*/#include
#include
#include
using
namespace
std;
// 抽象的部件類描述將來所有部件共有的行為
class component
virtual ~component(){}
virtual
void
operation
()= 0;
virtual
void
add(component *)
= 0;
virtual
void
remove
(component *)
= 0;
virtual component *getchild(int) = 0;
virtual
string
getname
() virtual
void
print
()= 0;
protected:
string m_strcompname;
};class leaf : public component
void
operation
() void
remove
(component *pcomponent)
{} component *getchild(int index)
void
print
(){}
};class composite : public component
~composite()
m_veccomp.erase(it);
it = m_veccomp.begin();}}
void
operation
() void
remove
(component *pcomponent)
m_veccomp.erase(it);
break;}}
}component *getchild(int index)
return m_veccomp[index - 1];
}void
print();
intmain
(int argc, char *ar**)
return
0;}
實現要點
composite的關鍵之一在於乙個抽象類,它既可以代表leaf,又可以代表composite;所以在實際實現時,應該最大化component介面,component類應為leaf和composite類盡可能多定義一些公共操作。component類通常為這些操作提供預設的實現,而leaf和composite子類可以對它們進行重定義;
component是否應該實現乙個component列表,在上面的**中,我是在composite中維護的列表,由於在leaf中,不可能存在子composite,所以在composite中維護了乙個component列表,這樣就減少了記憶體的浪費;
記憶體的釋放;由於存在樹形結構,當父節點都被銷毀時,所有的子節點也必須被銷毀,所以,我是在析構函式中對維護的component列表進行統一銷毀,這樣就可以免去客戶端頻繁銷毀子節點的困擾;
由於在component介面提供了最大化的介面定義,導致一些操作對於leaf節點來說並不適用,比如:leaf節點並不能進行add和remove操作,由於composite模式遮蔽了部分與整體的區別,為了防止客戶對leaf進行非法的add和remove操作,所以,在實際開發過程中,進行add和remove操作時,需要進行對應的判斷,判斷當前節點是否為composite。
組合模式的優點
將物件組合成樹形結構以表示「部分-整體」的層次結構。組合模式使得使用者對單個物件和組合物件的使用具有一致性。
使用場景
你想表示物件的部分-整體層次結構;
希望使用者忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。
引用大話設計模式的片段:「當發現需求中是體現部分與整體層次結構時,以及你希望使用者可以忽略組合物件與單個物件的不同,統一地使用組合結構中的所有物件時,就應該考慮組合模式了。」
總結通過上面的簡單講解,我們知道了,組合模式意圖是通過整體與區域性之間的關係,通過樹形結構的形式進行組織複雜物件,遮蔽物件內部的細節,對外展現統一的方式來操作物件,是我們處理更複雜物件的乙個手段和方式。現在再結合上面的**,想想文章開頭提出的公司oa系統如何進行設計。
C 設計模式 組合模式
一.概述 組合模式,將物件組合成樹形結構以表示 部分 整體 的層次結構,組合模式使得使用者對單個物件和組合物件的使用具有一致性。結構 1.component 是組合中的物件宣告介面,在適當的情況下,實現所有類共有介面的預設行為。宣告乙個介面用於訪問和管理component子部件。2.leaf 在組合...
C 設計模式 組合模式
一 組合模式的定義 組合多個物件形成樹形結構以表示具有部分 整體關係的層次結構。二 說明 組合模式關注那些包含葉子構件和容器構件的結構以及它們的組織形式,在葉子結構中不包含成員物件,而容器構件中包含成員物件,這些物件通過遞迴組合可構成乙個樹形結構。由於容器物件和葉子物件在功能上存在區別,因此在使用這...
C 設計模式 組合模式
ifndef composite h define composite h include include include 說明 組合模式的關鍵是定義了乙個抽象構件類,它既可以代表葉子,又可以代表容器,而客戶端針對該抽象構件類進行程式設計,無須知道它到底表示的是葉子還是容器,可以對其進行統一處理。同...