最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2014年09月30日 16:16:15   作者:果凍想  
這篇文章主要介紹了C++設(shè)計(jì)模式之組合模式,本文講解什么是組合模式、組合模式的優(yōu)點(diǎn)、組合模式實(shí)例等內(nèi)容,需要的朋友可以參考下

問(wèn)題描述

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

什么是組合模式?

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

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

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

UML類圖

Component:

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

Leaf:

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

Composite:

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

Client:

3.通過(guò)Component接口操作組合部件的對(duì)象。

代碼實(shí)現(xiàn)

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

/*
** FileName     : CompositePatternDemo
** Author       : Jelly Young
** Date         : 2013/12/09
** Description  : More information, please go to http://www.fzitv.net
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 抽象的部件類描述將來(lái)所有部件共有的行為
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;
}

實(shí)現(xiàn)要點(diǎn)

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

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

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

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

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

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

使用場(chǎng)景

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

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

總結(jié)

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

相關(guān)文章

  • QT進(jìn)行CSV文件初始化與讀寫操作

    QT進(jìn)行CSV文件初始化與讀寫操作

    這篇文章主要為大家詳細(xì)介紹了在QT環(huán)境中如何進(jìn)行CSV文件的初始化、寫入和讀取操作,本文為大家整理了相關(guān)的操作的多種方法,希望對(duì)大家有所幫助
    2025-04-04
  • C語(yǔ)言中棧的結(jié)構(gòu)和函數(shù)接口的使用示例

    C語(yǔ)言中棧的結(jié)構(gòu)和函數(shù)接口的使用示例

    這篇文章主要介紹了C語(yǔ)言中棧的結(jié)構(gòu)和函數(shù)接口的使用,類似很多軟件都有撤銷的操作,這其實(shí)就是用棧這種方法來(lái)實(shí)現(xiàn)的,當(dāng)然不同的軟件具體實(shí)現(xiàn)代碼會(huì)有差異,不過(guò)原理大多都是一樣的
    2023-02-02
  • C++中map容器的具體使用

    C++中map容器的具體使用

    本文主要介紹了C++中map容器的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C++實(shí)現(xiàn)優(yōu)先隊(duì)列的示例詳解

    C++實(shí)現(xiàn)優(yōu)先隊(duì)列的示例詳解

    普通的隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊(duì)列尾追加,而從隊(duì)列頭刪除。在優(yōu)先隊(duì)列中,元素被賦予優(yōu)先級(jí)。本文將用C++實(shí)現(xiàn)優(yōu)先隊(duì)列,需要的可以參考一下
    2022-06-06
  • C++實(shí)現(xiàn)LeetCode(56.合并區(qū)間)

    C++實(shí)現(xiàn)LeetCode(56.合并區(qū)間)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(56.合并區(qū)間),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)基于時(shí)序公平的讀寫鎖詳解

    C++實(shí)現(xiàn)基于時(shí)序公平的讀寫鎖詳解

    讀寫鎖與普通的互斥鎖的區(qū)別在于有兩種上鎖方式:讀鎖和寫鎖,不用的用戶對(duì)同一個(gè)讀寫鎖獲取讀鎖是非互斥的,其他情況則是互斥的,本文小編將給大家詳細(xì)介紹C++實(shí)現(xiàn)基于時(shí)序公平的讀寫鎖,需要的朋友可以參考下
    2023-10-10
  • 詳解C++如何實(shí)現(xiàn)在Word文檔中創(chuàng)建列表

    詳解C++如何實(shí)現(xiàn)在Word文檔中創(chuàng)建列表

    這篇文章主要為大家詳細(xì)介紹了介紹如何使用C++在Word文檔中創(chuàng)建編號(hào)列表、項(xiàng)目符號(hào)列表和多級(jí)列表,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • OpenCV圖像處理之圖像拼接詳解

    OpenCV圖像處理之圖像拼接詳解

    本文主要介紹了如何使用C++?OpenCV實(shí)現(xiàn)圖像景拼接,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定的幫助,感興趣的可以了解一下
    2022-08-08
  • C++實(shí)現(xiàn)簡(jiǎn)單版圖書管理系統(tǒng)

    C++實(shí)現(xiàn)簡(jiǎn)單版圖書管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單版圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳解C++中變量的初始化規(guī)則

    詳解C++中變量的初始化規(guī)則

    這篇文章詳細(xì)介紹了關(guān)于C++中變量的初始化規(guī)則,C++如果不對(duì)變量初始化,可能會(huì)導(dǎo)致很多后果,所以學(xué)習(xí)C++變量初始化規(guī)則就很重要了,下面一起來(lái)看看
    2016-08-08

最新評(píng)論

保山市| 饶平县| 江都市| 新野县| 榕江县| 定陶县| 万年县| 财经| 平南县| 扎赉特旗| 湟中县| 黄山市| 宿松县| 黄平县| 石棉县| 阳原县| 五大连池市| 略阳县| 凤城市| 赤峰市| 响水县| 蓬溪县| 都昌县| 隆化县| 靖西县| 宝清县| 沈阳市| 乐亭县| 孟州市| 栖霞市| 三门县| 潞城市| 读书| 黔南| 岳池县| 固阳县| 修水县| 锦屏县| 花垣县| 盖州市| 红原县|