C++設計形式之組合形式。本站提示廣大學習愛好者:(C++設計形式之組合形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C++設計形式之組合形式正文
成績描寫
上圖,是一個公司的組織構造圖,總手下面有多個子公司,同時總部也有各個部分,子公司上面有多個部分。假如對如許的公司開辟一個OA體系,作為法式員的你,若何設計這個OA體系呢?先不說若何設計完成,接著往下看,看完了上面的內容,再回過火來想怎樣設計如許的OA體系。
甚麼是組合形式?
在GOF的《設計形式:可復用面向對象軟件的基本》一書中對組合形式是如許說的:將對象組分解樹形構造以表現“部門-全體”的條理構造。組合(Composite)形式使得用戶對單個對象和組合對象的應用具有分歧性。
組合形式(Composite)將小對象組分解樹形構造,應用戶操作組合對象好像操作一個單個對象。組合形式界說了“部門-全體”的條理構造,根本對象可以被組分解更年夜的對象,並且這類操作是可反復的,赓續反復下去便可以獲得一個異常年夜的組合對象,但這些組合對象與根本對象具有雷同的接口,因此組合是通明的,用法完整分歧。
我們如許來簡略的懂得組合形式,組合形式就是把一些現有的對象或許元素,經由組合後構成新的對象,新的對象供給外部辦法,可讓我們很便利的完成這些元素或許外部對象的拜訪和操作。我們也能夠把組合對象懂得成一個容器,容器供給各類拜訪其外部對象或許元素的API,我們只須要應用這些辦法便可以操作它了。
UML類圖
Component:
1.為組合中的對象聲明接口;
2.在恰當的情形下,完成一切類共有接口的缺省行動;
3.聲明一個接口用於拜訪和治理Component的子組件。
Leaf:
1.在組合中表現葉節點對象,葉節點沒有子節點;
2.在組合中界說葉節點的行動。
Composite:
1.界說有子部件的那些部件的行動;
2.存儲子部件。
Client:
3.經由過程Component接口操作組合部件的對象。
代碼完成
/*
** FileName : CompositePatternDemo
** Author : Jelly Young
** Date : 2013/12/09
** Description : More information, please go to http://www.jb51.net
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 籠統的部件類描寫未來一切部件共有的行動
class Component
{
public:
Component(string name) : m_strCompname(name){}
virtual ~Component(){}
virtual void Operation() = 0;
virtual void Add(Component *) = 0;
virtual void Remove(Component *) = 0;
virtual Component *GetChild(int) = 0;
virtual string GetName()
{
return m_strCompname;
}
virtual void Print() = 0;
protected:
string m_strCompname;
};
class Leaf : public Component
{
public:
Leaf(string name) : Component(name)
{}
void Operation()
{
cout<<"I'm "<<m_strCompname<<endl;
}
void Add(Component *pComponent){}
void Remove(Component *pComponent){}
Component *GetChild(int index)
{
return NULL;
}
void Print(){}
};
class Composite : public Component
{
public:
Composite(string name) : Component(name)
{}
~Composite()
{
vector<Component *>::iterator it = m_vecComp.begin();
while (it != m_vecComp.end())
{
if (*it != NULL)
{
cout<<"----delete "<<(*it)->GetName()<<"----"<<endl;
delete *it;
*it = NULL;
}
m_vecComp.erase(it);
it = m_vecComp.begin();
}
}
void Operation()
{
cout<<"I'm "<<m_strCompname<<endl;
}
void Add(Component *pComponent)
{
m_vecComp.push_back(pComponent);
}
void Remove(Component *pComponent)
{
for (vector<Component *>::iterator it = m_vecComp.begin(); it != m_vecComp.end(); ++it)
{
if ((*it)->GetName() == pComponent->GetName())
{
if (*it != NULL)
{
delete *it;
*it = NULL;
}
m_vecComp.erase(it);
break;
}
}
}
Component *GetChild(int index)
{
if (index > m_vecComp.size())
{
return NULL;
}
return m_vecComp[index - 1];
}
void Print()
{
for (vector<Component *>::iterator it = m_vecComp.begin(); it != m_vecComp.end(); ++it)
{
cout<<(*it)->GetName()<<endl;
}
}
private:
vector<Component *> m_vecComp;
};
int main(int argc, char *argv[])
{
Component *pNode = new Composite("Beijing Head Office");
Component *pNodeHr = new Leaf("Beijing Human Resources Department");
Component *pSubNodeSh = new Composite("Shanghai Branch");
Component *pSubNodeCd = new Composite("Chengdu Branch");
Component *pSubNodeBt = new Composite("Baotou Branch");
pNode->Add(pNodeHr);
pNode->Add(pSubNodeSh);
pNode->Add(pSubNodeCd);
pNode->Add(pSubNodeBt);
pNode->Print();
Component *pSubNodeShHr = new Leaf("Shanghai Human Resources Department");
Component *pSubNodeShCg = new Leaf("Shanghai Purchasing Department");
Component *pSubNodeShXs = new Leaf("Shanghai Sales department");
Component *pSubNodeShZb = new Leaf("Shanghai Quality supervision Department");
pSubNodeSh->Add(pSubNodeShHr);
pSubNodeSh->Add(pSubNodeShCg);
pSubNodeSh->Add(pSubNodeShXs);
pSubNodeSh->Add(pSubNodeShZb);
pNode->Print();
// 公司不景氣,須要封閉上海質量監視部分
pSubNodeSh->Remove(pSubNodeShZb);
if (pNode != NULL)
{
delete pNode;
pNode = NULL;
}
return 0;
}
完成要點
1.Composite的症結之一在於一個籠統類,它既可以代表Leaf,又可以代表Composite;所以在現實完成時,應當最年夜化Component接口,Component類應為Leaf和Composite類盡量多界說一些公共操作。Component類平日為這些操作供給缺省的完成,而Leaf和Composite子類可以對它們停止重界說;
2.Component能否應當完成一個Component列表,在下面的代碼中,我是在Composite中保護的列表,因為在Leaf中,弗成能存在子Composite,所以在Composite中保護了一個Component列表,如許就削減了內存的糟蹋;
3.內存的釋放;因為存在樹形構造,當父節點都被燒毀時,一切的子節點也必需被燒毀,所以,我是在析構函數中對保護的Component列表停止同一燒毀,如許便可以避免去客戶端頻仍燒毀子節點的困擾;
4.因為在Component接口供給了最年夜化的接口界說,招致一些操尴尬刁難於Leaf節點來講其實不實用,好比:Leaf節點其實不能停止Add和Remove操作,因為Composite形式屏障了部門與全體的差別,為了避免客戶對Leaf停止不法的Add和Remove操作,所以,在現實開辟進程中,停止Add和Remove操作時,須要停止對應的斷定,斷定以後節點能否為Composite。
組合形式的長處
將對象組分解樹形構造以表現“部門-全體”的條理構造。組合形式使得用戶對單個對象和組合對象的應用具有分歧性。
應用場景
1.你想表現對象的部門-全體條理構造;
2.願望用戶疏忽組合對象與單個對象的分歧,用戶將同一地應用組合構造中的一切對象。
援用年夜話設計形式的片斷:“當發明需求中是表現部門與全體條理構造時,和你願望用戶可以疏忽組合對象與單個對象的分歧,同一地應用組合構造中的一切對象時,就應當斟酌組合形式了。”
總結
經由過程下面的簡略講授,我們曉得了,組合形式意圖是經由過程全體與部分之間的關系,經由過程樹形構造的情勢停止組織龐雜對象,屏障對象外部的細節,對外展示同一的方法來操尴尬刁難象,是我們處置更龐雜對象的一個手腕和方法。如今再聯合下面的代碼,想一想文章開首提出的公司OA體系若何停止設計。