国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++設(shè)計模式之組合模式

2020-05-23 14:21:15
字體:
供稿:網(wǎng)友
這篇文章主要介紹了C++設(shè)計模式之組合模式,本文講解什么是組合模式、組合模式的優(yōu)點、組合模式實例等內(nèi)容,需要的朋友可以參考下
 
 

問題描述

C++設(shè)計模式之組合模式

上圖,是一個公司的組織結(jié)構(gòu)圖,總部下面有多個子公司,同時總部也有各個部門,子公司下面有多個部門。如果對這樣的公司開發(fā)一個OA系統(tǒng),作為程序員的你,如何設(shè)計這個OA系統(tǒng)呢?先不說如何設(shè)計實現(xiàn),接著往下看,看完了下面的內(nèi)容,再回過頭來想怎么設(shè)計這樣的OA系統(tǒng)。

什么是組合模式?

在GOF的《設(shè)計模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中對組合模式是這樣說的:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。組合(Composite)模式使得用戶對單個對象和組合對象的使用具有一致性。

組合模式(Composite)將小對象組合成樹形結(jié)構(gòu),使用戶操作組合對象如同操作一個單個對象。組合模式定義了“部分-整體”的層次結(jié)構(gòu),基本對象可以被組合成更大的對象,而且這種操作是可重復(fù)的,不斷重復(fù)下去就可以得到一個非常大的組合對象,但這些組合對象與基本對象擁有相同的接口,因而組合是透明的,用法完全一致。

我們這樣來簡單的理解組合模式,組合模式就是把一些現(xiàn)有的對象或者元素,經(jīng)過組合后組成新的對象,新的對象提供內(nèi)部方法,可以讓我們很方便的完成這些元素或者內(nèi)部對象的訪問和操作。我們也可以把組合對象理解成一個容器,容器提供各種訪問其內(nèi)部對象或者元素的API,我們只需要使用這些方法就可以操作它了。

UML類圖

C++設(shè)計模式之組合模式

Component:

1.為組合中的對象聲明接口;
2.在適當(dāng)?shù)那闆r下,實現(xiàn)所有類共有接口的缺省行為;
3.聲明一個接口用于訪問和管理Component的子組件。

Leaf:

1.在組合中表示葉節(jié)點對象,葉節(jié)點沒有子節(jié)點;
2.在組合中定義葉節(jié)點的行為。

Composite:

1.定義有子部件的那些部件的行為;
2.存儲子部件。

Client:

3.通過Component接口操作組合部件的對象。

代碼實現(xiàn)

 

復(fù)制代碼代碼如下:

/*
** FileName     : CompositePatternDemo
** Author       : Jelly Young
** Date         : 2013/12/09
** Description  : More information, please go to http://www.survivalescaperooms.com
*/
#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();
     // 公司不景氣,需要關(guān)閉上海質(zhì)量監(jiān)督部門
     pSubNodeSh->Remove(pSubNodeShZb);
     if (pNode != NULL)
     {
          delete pNode;
          pNode = NULL;
     }
     return 0;
}

 

實現(xiàn)要點

1.Composite的關(guān)鍵之一在于一個抽象類,它既可以代表Leaf,又可以代表Composite;所以在實際實現(xiàn)時,應(yīng)該最大化Component接口,Component類應(yīng)為Leaf和Composite類盡可能多定義一些公共操作。Component類通常為這些操作提供缺省的實現(xiàn),而Leaf和Composite子類可以對它們進行重定義;

2.Component是否應(yīng)該實現(xiàn)一個Component列表,在上面的代碼中,我是在Composite中維護的列表,由于在Leaf中,不可能存在子Composite,所以在Composite中維護了一個Component列表,這樣就減少了內(nèi)存的浪費;

3.內(nèi)存的釋放;由于存在樹形結(jié)構(gòu),當(dāng)父節(jié)點都被銷毀時,所有的子節(jié)點也必須被銷毀,所以,我是在析構(gòu)函數(shù)中對維護的Component列表進行統(tǒng)一銷毀,這樣就可以免去客戶端頻繁銷毀子節(jié)點的困擾;

4.由于在Component接口提供了最大化的接口定義,導(dǎo)致一些操作對于Leaf節(jié)點來說并不適用,比如:Leaf節(jié)點并不能進行Add和Remove操作,由于Composite模式屏蔽了部分與整體的區(qū)別,為了防止客戶對Leaf進行非法的Add和Remove操作,所以,在實際開發(fā)過程中,進行Add和Remove操作時,需要進行對應(yīng)的判斷,判斷當(dāng)前節(jié)點是否為Composite。

組合模式的優(yōu)點

將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。組合模式使得用戶對單個對象和組合對象的使用具有一致性。

使用場景

1.你想表示對象的部分-整體層次結(jié)構(gòu);
2.希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象。

引用大話設(shè)計模式的片段:“當(dāng)發(fā)現(xiàn)需求中是體現(xiàn)部分與整體層次結(jié)構(gòu)時,以及你希望用戶可以忽略組合對象與單個對象的不同,統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象時,就應(yīng)該考慮組合模式了。”

總結(jié)

通過上面的簡單講解,我們知道了,組合模式意圖是通過整體與局部之間的關(guān)系,通過樹形結(jié)構(gòu)的形式進行組織復(fù)雜對象,屏蔽對象內(nèi)部的細(xì)節(jié),對外展現(xiàn)統(tǒng)一的方式來操作對象,是我們處理更復(fù)雜對象的一個手段和方式。現(xiàn)在再結(jié)合上面的代碼,想想文章開頭提出的公司OA系統(tǒng)如何進行設(shè)計。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 绵竹市| 通榆县| 明水县| 湄潭县| 临夏县| 汝阳县| 正定县| 桂林市| 边坝县| 红桥区| 余姚市| 绥芬河市| 永新县| 景德镇市| 稻城县| 新密市| 开鲁县| 陆川县| 石家庄市| 锦屏县| 弋阳县| 土默特左旗| 祁阳县| 称多县| 山西省| 青海省| 商洛市| 丽江市| 昆明市| 九江县| 新乡县| 同仁县| 马公市| 新宾| 宁蒗| 长沙县| 炉霍县| 吐鲁番市| 宣汉县| 申扎县| 甘谷县|