【C++設計模式】組合模式
索引目錄
1 含義
組合多個物件形成樹形結構以表示“部分-整體”的結構層次。組合模式對單個物件(葉子物件)和組合物件(容器物件)的使用具有一致性。
2 模式結構
3 程式碼實現
舉例:假設你要開一家公司,要招募大量員工,當然有經理,主管,普通員工,相信再小的公司都會有這樣的組織架構。經理管主管,主管又管普通員工,普通員工自己管自己
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//員工:抽象物件Component
class Employee
{
protected:
string m_Name;
string m_job;
public:
Employee(string name,string job):m_Name(name),m_job(job){}
virtual void add(Employee* subordinate) = 0;
virtual void remove(Employee*subordinate) = 0;
virtual void showMe()=0;
};
//設計員
class Designer: public Employee
{
public:
Designer(string name,string job):Employee(name,job){}
void add(Employee* subordinate) override
{
cout << "我是小員工,管理不了人!" << endl;
}
void remove(Employee*subordinate)override
{
cout << "我是小員工,沒人歸我管理!" << endl;
}
void showMe()override
{
cout << "姓名:" << m_Name << "--" << "職位:" << m_job << endl;;
}
};
//主管或經理:枝節點實現
class Manger :public Employee
{
private:
vector<Employee*>m_Subordinates;
public:
Manger(string name, string job) :Employee(name, job) {}
void add(Employee* subordinate) override
{
m_Subordinates.push_back(subordinate);
}
void remove(Employee* subordinate) override
{
vector<Employee*>::iterator it = m_Subordinates.begin();
while (it!=m_Subordinates.end())
{
if(*it==subordinate)
{
m_Subordinates.erase(it);
delete subordinate;
subordinate = nullptr;
break;
}
it++;
}
}
//顯示自己及手下
void showMe()override
{
cout << "姓名:" << m_Name << "--" << "職位:" << m_job << endl;
cout << m_Name << "手下有:";
//顯示子節點
vector<Employee*>::iterator it = m_Subordinates.begin();
while (it != m_Subordinates.end())
{
(*it)->showMe();
++it;
}
}
};
int main()
{
//招收員工,從上到下
Employee *manager = new Manger("小強", "經理");
Employee *supervisor = new Manger("小明", "主管");
Employee *supervisor1 = new Manger("小英", "主管");
Employee *staff1 = new Designer("小李", "設計員");
Employee *staff2 = new Designer("小王", "設計員");
//組織公司架構
manager->add(supervisor);
manager->add(supervisor1);
supervisor->add(staff1);
supervisor1->add(staff2);
manager->showMe();
staff2->add(manager);
return 0;
}
4 優缺點
優點:
利用多型和遞迴機制更方便地使用複雜樹結構。
缺點:
對於功能差異較大的類, 提供公共介面或許會有困難。 在特定情況下, 你需要過度一般化元件介面, 使其變得令人難以理解。
5 適用場景
需要實現樹狀物件結構, 可以使用組合模式
6.模式擴充套件
橋接模式、 狀態模式和策略模式 (在某種程度上包括介面卡模式) 模式的介面非常相似。 實際上, 它們都基於組合模式——即將工作委派給其他物件, 不過也各自解決了不同的問題。 模式並不只是以特定方式組織程式碼的配方, 你還可以使用它們來和其他開發者討論模式所解決的問題。
你可以在建立複雜組合樹時使用生成器模式, 因為這可使其構造步驟以遞迴的方式執行。
責任鏈模式通常和組合模式結合使用。 在這種情況下, 葉元件接收到請求後, 可以將請求沿包含全體父元件的鏈一直傳遞至物件樹的底部。
你可以使用迭代器模式來遍歷組合樹。
你可以使用訪問者模式對整個組合樹執行操作。
你可以使用享元模式實現組合樹的共享葉節點以節省記憶體。
組合和裝飾模式的結構圖很相似, 因為兩者都依賴遞迴組合來組織無限數量的物件。
裝飾類似於組合, 但其只有一個子元件。 此外還有一個明顯不同: 裝飾為被封裝物件新增了額外的職責, 組合僅對其子節點的結果進行了 “求和”。
但是, 模式也可以相互合作: 你可以使用裝飾來擴充套件組合樹中特定物件的行為。
大量使用組合和裝飾的設計通常可從對於原型模式的使用中獲益。 你可以通過該模式來複制複雜結構, 而非從零開始重新構造。
參考
1.https://refactoringguru.cn/design-patterns/composite
2.https://blog.csdn.net/a369189453/article/details/81193415
3.https://blog.csdn.net/lxq1997/article/details/89460373
相關文章
- [C++設計模式] composite 組合模式C++設計模式
- 【設計模式】組合模式設計模式
- 設計模式《組合模式》設計模式
- 設計模式-組合模式設計模式
- 設計模式:組合模式設計模式
- js設計模式–組合模式JS設計模式
- js設計模式--組合模式JS設計模式
- 設計模式系列 – 組合模式設計模式
- javascript設計模式組合模式JavaScript設計模式
- 設計模式(十三):組合模式設計模式
- PHP 設計模式之組合模式PHP設計模式
- GoLang設計模式20 - 組合模式Golang設計模式
- 設計模式【11】-- 搞定組合模式設計模式
- 徒手擼設計模式-組合模式設計模式
- 極簡設計模式-組合模式設計模式
- 設計模式系列之「組合模式」設計模式
- 大話設計模式—組合模式設計模式
- 23種設計模式之組合模式設計模式
- 《Head First 設計模式》:組合模式設計模式
- Java設計模式之(十)——組合模式Java設計模式
- 【趣味設計模式系列】之【組合模式】設計模式
- javascript設計模式 之 7組合模式JavaScript設計模式
- 設計模式系列7--組合模式設計模式
- 設計模式漫談之組合模式設計模式
- C#設計模式之組合模式C#設計模式
- c#設計模式_全部部分模式_組合模式C#設計模式
- 《設計模式四》觀察、組合、享元模式設計模式
- 設計模式之組合模式(Composite)分享設計模式
- 設計模式 | 組合模式及典型應用設計模式
- Java設計模式學習08——組合模式Java設計模式
- 《設計模式》 - 7. 組合模式( Composite )設計模式
- 設計模式之組合模式---Composite Pattern設計模式
- 我所理解的設計模式(C++實現)——組合模式(Composite Pattern)設計模式C++
- 設計模式(十四、十五)----結構型模式之組合模式設計模式
- JavaScript設計模式之策略模式【組合委託】JavaScript設計模式
- 設計模式(十)——組合模式(HashMap原始碼解析)設計模式HashMap原始碼
- 每天一個設計模式之組合模式設計模式
- C#設計模式-組合模式(Composite Pattern)C#設計模式