组合模式

组合模式的核心思想就是:一个组织有很多子组织,而无论子组织是单独一个部门或是一个分组织。该组织都希望把它们当成一样的子组织来管理。对于分组织,只用通知分组织就可以了,而不用一一通知分组织的各个部门。

  1. 组件(Component):为组合中的对象声明接口,声明了类共有接口的缺省行为(如这里的Add,Remove,GetChild函数),声明一个接口函数可以访问Component的子组件。
    1). Component::ComponentPtr:定义了各个组件共有的行为接口,由各个组件的具体实现.
    2). Component::add添加一个子组件
    3). Component::remove::删除一个子组件.
    4). Component::display:获得子组件的指针.

  2. 容器(Composite):是含有子组件的类,其内部包含了多种方法,主要是在当中实现了add与remove这类的操作用于对子组件进行控制。

  3. 叶节点(Leaf):是叶子结点,也就是不含有子组件的结点。

示例:

// CompositeModel.h文件
//#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <memory>

class ComponentPtr
{
protected:
    std::string m_strName;
public:
    ComponentPtr(std::string str)
    {
        m_strName = str;
    }
    virtual void add(ComponentPtr * p) = 0;
    virtual void remove(ComponentPtr * p) = 0;
    virtual void display() = 0;
};

class LeafPtr : public ComponentPtr
{
public:
    LeafPtr(std::string str) : ComponentPtr(str) {}
    void add(ComponentPtr * p)
    {
        std::cout << "Leaf cannot add" << std::endl;
    }
    void remove(ComponentPtr * p)
    {
        std::cout << "Leaf cannot remove" << std::endl;
    }
    void display()
    {
        std::cout << m_strName << std::endl;
    }
};

class CompositePtr : public ComponentPtr
{
public:
    CompositePtr(std::string str) : ComponentPtr(str) {};
    ~CompositePtr()
    {
        if (!m_vec.empty())
        {
            m_vec.clear();
        }
    }
    void add(ComponentPtr * p)
    {
        auto it = find_if(m_vec.begin(), m_vec.end(),
            [p](std::shared_ptr<ComponentPtr> ptr) {return p == ptr.get(); });
        if (it == m_vec.end())
            m_vec.push_back(std::shared_ptr<ComponentPtr>(p));
    }
    void remove(ComponentPtr * p)
    {
        auto it = find_if(m_vec.begin(), m_vec.end(),
            [p](std::shared_ptr<ComponentPtr> ptr) {return p == ptr.get(); });
        if (it == m_vec.end())
            return;
        m_vec.erase(it);
    }
    void display()
    {
        for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++)
        {
            (*it)->display();
        }
    }
private:
    // 这里使用智能指针不用自己释放new的内存
    std::vector<std::shared_ptr<ComponentPtr>> m_vec;
};


/**
#include <iostream>
#include "CompositeModel.h"
**/

int main()
{
    using namespace std;
    // 组合模式
    CompositePtr * p = new CompositePtr("总部");
    p->add(new LeafPtr("总部财务部门"));
    p->add(new LeafPtr("总部人力资源部门"));
    CompositePtr * p1 = new CompositePtr("上海分部");
    p1->add(new LeafPtr("上海分部财务部门"));
    p1->add(new LeafPtr("上海分部人力资源部门"));
    p->add(p1);
    p->display();

    getchar();
    return 0;
}

输出:

总部财务部门
总部人力资源部门
上海分部财务部门
上海分部人力资源部门




参考:

https://www.guyuehome.com/37300

posted @   double64  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示