【设计模式】之二十三种设计模式--组合模式

组合模式

Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.

(将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。)

通用类图

抽象构件角色类

定义参加组合对象的公有方法和属性,可以定义一下默认的行为或属性

叶子构件类

叶子对象,其下再也没有其他的分支,遍历的最小单位,继承抽象构件角色类

树枝构件类

组合树枝节点和叶子节点形成一个树形结构,继承抽象构件角色类,并且与之是整体与部分关系

通用源码

//抽象构件类
class Component {
public:
    virtual void doSomething() {
        //业务逻辑
    }
};
//树枝构件类,组合模式的重点
class Composite : public Component {
private:
    //构件容器
    vector<Component*> vc;
public:
    //增加一个叶子构件或树枝构件
    void add(Component *c) { vc.push_back(c);}
    //删除一个叶子构件或树枝构件
    void remove(Component *c) {
        auto iter = vc.find(vc.begin(), vc.end(), c);
        vc.erase(c);
    }
    //获得分支下的所有叶子构件和树枝构件
    vector<Component*> getChildren() {
        return vc;
    }
};
//叶子构件类
class Leaf : public Component {
public:
    void doSomething() {
    }
};

优点

高层模块调用简单

节点自由增加,符合开闭原则

缺点

违背依赖倒置原则,没有面向接口编程

使用场景

维护和展示部分-整体的场景,如树性菜单、文件和文件夹管理

从一个整体中能够独立出部分模块或功能的场景

扩展

与关系数据库结合使用,能够轻松的实现树的组装

透明的组合模式,把树枝构件中的方法放到抽象类中实现,遵循依赖倒置原则

组合模式的遍历,增加设置父节点的方法,实现从底往上的遍历

示例代码

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Corp {
public:
    Corp(const string& n, const string& p, int s): name(n), position(p), salary(s) { }
    string getinfo() {
        string info = name + ", "+ position + ", ";
        info += to_string(salary);
        return info;
    }
private:
    string name;
    string position;
    int salary;
};

class Leaf : public Corp {
public:
    Leaf(const string& n, const string& p, int s): Corp(n, p, s) { }
};

class Branch : public Corp {
public:
    Branch(const string& n, const string& p, int s): Corp(n, p, s){ }
    void addSubordinate(Corp *ic) {
        vIc.push_back(ic);
    }
    vector<Corp*> getSubordinate() {
        return vIc;
    }
private:
    vector<Corp*> vIc;
};

int main() {
    Branch ceo("zzzl", "ceo", 10000);
    Branch dev("lzzl", "dev", 8000);
    Branch sal("llzl", "sal", 8000);
    Leaf a("zzl1", "dev1", 5000);
    Leaf b("zzl2", "dev2", 5000);
    Leaf c("lzl1", "sal1", 5000);
    Leaf d("lzl2", "sal2", 5000);
    Leaf e("lll", "ass", 5000);
    ceo.addSubordinate(&dev);
    ceo.addSubordinate(&sal);
    ceo.addSubordinate(&e);
    dev.addSubordinate(&a);
    dev.addSubordinate(&b);
    sal.addSubordinate(&c);
    sal.addSubordinate(&d);
    cout << ceo.getinfo() << endl;
    vector<Branch> vb;
    vb.push_back(ceo);
    vb.push_back(dev);
    vb.push_back(sal);
    for(i : vb) {
        vector<Corp*> v = i.getSubordinate();
        for(j : v)
            cout << j->getinfo() << endl;
    }
    return 0;
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦