C++设计模式(十五)—组合模式

组合模式

将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使用的用户对单个对象和组合对象的使用具有一致性。
本文使用书中公司管理系统的事例,代码使用C++语言描述,代码存在的不足或问题有望各位指出。
(1)组合模式代码框架

//组合模式
#include <iostream>
#include <string>
#include <vector>
#include <string>
using namespace std;
class Component
{
public:
    Component(){}
    virtual ~Component(){}
    Component(string name)
    {
        this->name =name;
    }
    virtual void Add(Component *c)=0;
    virtual void Remove(Component *c)=0;
    virtual void Display(int depth) =0;
protected:
    string name;

};

class Leaf: public Component
{
public:
    Leaf(){}
    ~Leaf(){}
    Leaf(string name)
    {
        this->name =name;
    }
    void Add(Component *c) override
    {
        cout <<"Cannot add to a leaf!"<<endl;
    }
    void Remove(Component *c) override
    {
        cout << "Cannot remove from a leaf!" <<endl;
    }
    void Display(int depth) override
    {
        while(depth > 0)
        {
            cout << "_" ;
            depth--;
        }
        cout << name<<endl;
    }

};
class Composite: public Component
{
public:
    Composite(){}
    ~Composite(){}
    Composite(string name)
    {
        this->name =name;
    }
    void Add(Component *c) override
    {
        children.push_back(c);
    }
    void Remove(Component *c) override
    {
        auto it = children.begin();
        for(;it !=children.end();it++)
        {
            if(*it == c)
                break;
        }
        if(it!=children.end())
        {
            children.erase(it);
        }
    }
    void Display(int depth) override
    {
        int depthOri = depth;
        while(depth>0)
        {
            cout <<'_';
            depth--;
        }
        cout <<name<<endl;
        for(auto c:children)
            c->Display(depthOri+2);
    }
private:
    vector<Component*> children;


};

int main()
{
    Composite *root = new Composite("root");
    root->Add(new Leaf("Leaf A"));
    root->Add(new Leaf("Leaf B"));

    Composite *comp = new Composite("Composite X");
    comp->Add(new Leaf("Leaf XA"));
    comp->Add(new Leaf ("Leaf XB"));

    root->Add(comp);

    Composite *comp2 =new Composite("Composite XY");
    comp2->Add(new Leaf("Leaf XYA"));
    comp2->Add(new Leaf("Leaf XYB"));
    comp->Add(comp2);

    root->Add(new Leaf("Leaf C"));
    Leaf *leaf = new Leaf("leaf D");
    root->Add(leaf);
    root->Remove(leaf);

    root->Display(1);

    delete root;
    delete comp;
    delete comp2;
    delete leaf;

    return 0;
}
(2)公司管理系统使用组合模式
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Company
{
public:
    Company(){}
    virtual ~Company(){}
    Company(string name)
    {
        this->name =name;
    }
    virtual void Add(Company *c) =0;
    virtual void Remove(Company *c) =0;
    virtual void Display(int depth) =0;
    virtual void lineOfDuty() =0;
protected:
    string name;
};

class ConcreteCompany :public Company
{
public:
    ConcreteCompany(){}
    ~ConcreteCompany(){}
    ConcreteCompany(string name)
    {
        this->name =name;
    }
    void Add(Company *c) override
    {
        children.push_back(c);
    }
    void Remove(Company *c) override
    {
        auto it = children.begin();
        for(;it!=children.end();it++)
        {
            if(*it ==c)
                break;
        }
        if(it!=children.end())
        {
            children.erase(it);
        }
    }
    void Display( int depth) override
    {
        int depthOri = depth;
        while(depth>0)
        {
            cout <<'_';
            depth--;
        }
        cout <<name<<endl;
        for(auto c:children)
            c->Display(depthOri+2);

    }

    void lineOfDuty() override
    {
        for(auto c:children)
        {
            c->lineOfDuty();
        }
    }
private:
    vector<Company*>children;

};


class HRDepartment : public Company
{
public:
    HRDepartment(){}
    ~HRDepartment(){}
    HRDepartment(string name)
    {
        this->name =name;
    }
    void Add(Company *c) override
    {

    }
    void Remove(Company *c) override
    {

    }
    void Display(int depth) override
    {
        while(depth>0)
        {
            cout <<'_';
            depth--;
        }
        cout <<name<<endl;
    }

    void lineOfDuty() override
    {
        cout << name << "员工招聘培训管理" <<endl;
    }

};

class FinanceDepartment : public Company
{
public:
    FinanceDepartment(){}
    ~FinanceDepartment(){}
    FinanceDepartment(string name)
    {
        this->name =name;
    }
    void Add(Company *c) override
    {
    }
    void Remove(Company *c) override
    {

    }
    void Display(int depth) override
    {
        while(depth>0)
        {
            cout <<"_";
            depth--;
        }
        cout << name<<endl;
    }

    void lineOfDuty() override
    {
        cout << name <<"公司财务收支管理"<<endl;
    }
private:



};

int main()
{
    ConcreteCompany *root = new ConcreteCompany("北京总公司");
    root->Add(new HRDepartment("总公司人力资源部"));

    ConcreteCompany *comp = new ConcreteCompany("上海华东分公司");
    comp->Add(new HRDepartment("华东分公司人力资源部"));
    comp->Add(new FinanceDepartment("华东分公司财务部"));
    root->Add(comp);

    ConcreteCompany *comp1 = new ConcreteCompany("南京办事处");
    comp1->Add(new HRDepartment("南京办事处人力资源部"));
    comp1->Add(new FinanceDepartment("南京办事处财务部"));
    root->Add(comp1);

    ConcreteCompany *comp2 = new ConcreteCompany("杭州办事处");
    comp2->Add(new HRDepartment("杭州办事处人力资源部"));
    comp2->Add(new FinanceDepartment("杭州办事处财务部"));
    root->Add(comp2);

    root->Display(1);
    root->lineOfDuty();

    delete root;
    delete comp;
    delete comp1;
    delete comp2;
    return 0;

}

组合模式的好处

1、组合模式这样就定义了包含人力资源部和财务部这些基本对象和分公司、办事处等组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户端代码,任何用到基本对象的地方都可以使用组合对象了。

2、用户是不用关心到底是处理一个叶结点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了。

3、组合模式让客户可以一致地使用组合结构和单个对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThomasKUI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值