系列文章目錄
C++技能系列
Linux通信架構(gòu)系列
C++高性能優(yōu)化編程系列
深入理解軟件架構(gòu)設(shè)計(jì)系列
高級C++并發(fā)線程編程
設(shè)計(jì)模式系列
期待你的關(guān)注哦?。?!
現(xiàn)在的一切都是為將來的夢想編織翅膀,讓夢想在現(xiàn)實(shí)中展翅高飛。
Now everything is for the future of dream weaving wings, let the dream fly in reality.
一、組合模式介紹
?? 意圖:
將對象組合成樹形結(jié)構(gòu)以表示"部分-整體"的層次結(jié)構(gòu)。組合模式使得用戶對單個(gè)對象和組合對象的使用具有一致性。
?? 主要解決:
它在我們樹型結(jié)構(gòu)的問題中,模糊了簡單元素和復(fù)雜元素的概念,客戶程序可以像處理簡單元素一樣來處理復(fù)雜元素,從而使得客戶程序與復(fù)雜元素的內(nèi)部結(jié)構(gòu)解耦。
?? 何時(shí)使用:
1、您想表示對象的部分-整體層次結(jié)構(gòu)(樹形結(jié)構(gòu))。 2、您希望用戶忽略組合對象與單個(gè)對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象。
?? 如何解決:
樹枝和葉子實(shí)現(xiàn)統(tǒng)一接口,樹枝內(nèi)部組合該接口。
現(xiàn)有一個(gè)公司需要實(shí)現(xiàn)一個(gè)廣播的功能,用來通知給公司所有部門重要的信息。如果需要廣播,那么必須通過每一個(gè)部門類的實(shí)例去調(diào)用各自部門的廣播接口。通過一個(gè)抽象類來抽象出廣播接口,各個(gè)部門和公司都通過繼承實(shí)現(xiàn)抽象接口。如此實(shí)現(xiàn)可以將所有部門放在一個(gè)容器內(nèi),遍歷實(shí)現(xiàn)其廣播接口。如果公司不擴(kuò)大,永遠(yuǎn)有這幾個(gè)部門并且沒有分公司的話,是沒問題的。如果再要添加一個(gè)部門,就必須實(shí)現(xiàn)一個(gè)部門類,再修改總公司類。這明顯違背了開閉原則。既然我們通過抽象類來實(shí)現(xiàn)了其方法,那就可以實(shí)現(xiàn)抽象的增加,刪除,查詢接口。如此一來,如果要有新的部門, 那么只需要通過調(diào)用添加接口來增加新部門, 廣播的時(shí)候,只需要遍歷容器中的廣播接口即可。實(shí)現(xiàn)類圖如下:
組合模式,將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對單個(gè)對象和組合對象的使用具有一致性。掌握組合模式的重點(diǎn)是要理解清楚 “部分/整體” 還有 ”單個(gè)對象“ 與 “組合對象” 的含義。
組合模式可以讓客戶端像修改配置文件一樣簡單的完成本來需要流程控制語句來完成的功能。
二、組合模式優(yōu)缺點(diǎn)
2.1 優(yōu)點(diǎn)
- 簡化客戶端調(diào)用,實(shí)現(xiàn)符合開閉原則。
- 高層模塊調(diào)用簡單。
- 節(jié)點(diǎn)自由增加
2.2 缺點(diǎn)
-
如果業(yè)務(wù)邏輯負(fù)責(zé),則實(shí)現(xiàn)組合模式比較困難。
-
在使用組合模式時(shí),其葉子和樹枝的聲明都是實(shí)現(xiàn)類,而不是接口,違反了依賴倒置原則。
三、組合模式使用場景
適用于“整體-部分”層次的樹形結(jié)構(gòu)的。部分、整體場景,如樹形菜單,文件、文件夾的管理。
客戶端對組合對象統(tǒng)一的使用所有對象。
四、組合模式實(shí)現(xiàn)
Component.h
#ifndef COMPONENTS_H_
#define COMPONENTS_H_
#include <iostream>
#include <vector>
using namespace std;
class Components
{
public:
Components(std::string strName):m_strName(strName){}
virtual void Operation() = 0;
virtual void AddSubCompany(Components* subCompany);
virtual void DelSubCompany(Components* subCompany);
virtual Components* GetCompanyByIndex(int iIndex);
protected:
std::string m_strName;
};
class ConcreteCompany : public Components
{
public:
ConcreteCompany(std::string strName):Components(strName){}
~ConcreteCompany();
virtual void Operation();
virtual void AddSubCompany(Components* subCompany);
virtual void DelSubCompany(Components* subCompany);
virtual Components* GetCompanyByIndex(int iIndex);
private:
std::vector<Components*> m_vecSubItem;
};
class FinanceDepartment : public Components
{
public:
FinanceDepartment(std::string strName):Components(strName){}
virtual void Operation();
};
class HRDepartment : public Components
{
public:
HRDepartment(std::string strName):Components(strName){}
virtual void Operation();
};
#endif
Component.cpp
#include "Company.h"
#include <algorithm>
#ifndef SAFE_DELETE
#define SAFE_DELETE(p){if((p) != NULL){delete (p); (p) = NULL;}}
#endif
void Components::AddSubCompany( Components* subCompany )
{
cout << "Have no realized!" << endl;
}
void Components::DelSubCompany( Components* subCompany )
{
cout << "Have no realized!" << endl;
}
Components* Components::GetCompanyByIndex( int iIndex )
{
cout << "Have no realized!" << endl;
return NULL;
}
//******************//
//**CentralCompany**//
//******************//
ConcreteCompany::~ConcreteCompany()
{
std::for_each(m_vecSubItem.begin(),m_vecSubItem.end(),[&](Components* item)
{
SAFE_DELETE(item);
});
}
void ConcreteCompany::Operation()
{
std::for_each(m_vecSubItem.begin(),m_vecSubItem.end(),[&](Components* item)
{
item->Operation();
});
}
void ConcreteCompany::AddSubCompany( Components* subCompany )
{
if (subCompany != NULL)
{
m_vecSubItem.push_back(subCompany);
}
}
void ConcreteCompany::DelSubCompany( Components* subCompany )
{
for (auto it = m_vecSubItem.begin(); it != m_vecSubItem.end(); ++it)
{
if ((*it) == subCompany)
{
m_vecSubItem.erase(it);
SAFE_DELETE(subCompany);
break;
}
}
}
Components* ConcreteCompany::GetCompanyByIndex( int iIndex )
{
if (iIndex < 0 || iIndex > m_vecSubItem.size())
{
return NULL;
}
return m_vecSubItem[iIndex];
}
void FinanceDepartment::Operation()
{
cout << m_strName.c_str() << endl;
}
void HRDepartment::Operation()
{
cout << m_strName.c_str() << endl;
}
main.cpp文章來源:http://www.zghlxwxcb.cn/news/detail-606813.html
#include <iostream>
#include "Company.h"
using namespace std;
int main()
{
Components* Central = new ConcreteCompany("Central Company");
Central->AddSubCompany(new FinanceDepartment("Central Finance Department"));
Central->AddSubCompany(new HRDepartment("Central HR Department"));
Components* Xian = new ConcreteCompany("Xi'An Company");
Xian->AddSubCompany(new FinanceDepartment("Xi'An Finance Department"));
Xian->AddSubCompany(new HRDepartment("Xi'An HR Department"));
Central->AddSubCompany(Xian);
Central->Operation();
cout << "<<<<<>>>>>" << endl;
Central->DelSubCompany(Xian);
Central->Operation();
return 0;
}
輸出:文章來源地址http://www.zghlxwxcb.cn/news/detail-606813.html
Central Finance Department
Central HR Department
Xi’An Finance Department
Xi’An HR Department
<<<<<>>>>>
Central Finance Department
Central HR Department
到了這里,關(guān)于結(jié)構(gòu)型設(shè)計(jì)模式之組合模式【設(shè)計(jì)模式系列】的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!