设计模式之组合模式(Composite)的C++实现

1、组合模式的提出

在软件开发过程中,使用者Client过多依赖所操作对象内部的实现结构,如果对象内部的实现结构频繁发生变化,则使用者的代码结构将要频繁地修改,不利于代码地维护和扩展性;组合模式可以解决此类问题。组合模式可以使用者代码与复杂地操作对象结构进行解耦,根据操作对象的实现结构抽象出一个的基类,让操作对象内部根据需求变化实现复杂数据地操作接口,则使用者使用操作对象提供的统一接口就可完成功能。

2、需求描述

有根节点、子节点、叶子节点,这三种节点都有自己的名字。操作规则:根节点下面可以添加子节点和叶子节点;子节点下面可以添加子子节点和叶子节点;叶子节点下面不能再添加其他节点。

设计一个功能代码,模拟上面的节点添加规则,使用者可以访问这些节点的数据结构。

3、功能实现

(1)UML图如下:

                           ​​​​​​

 (2)代码实现如下:

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

class Component
{
protected:
    std::string m_strName;
public:
    Component(std::string name):m_strName(std::move(name)){};
    virtual void operation() const =0;
    std::string getName(){return m_strName;};
    virtual ~Component(){};
};

class Leaf:public Component
{
public:
    explicit Leaf(std::string name):Component(name){
    };
    virtual void operation() const override
    {
        std::cout << "Leaf: " << m_strName << std::endl;
    };
};

class Composite:public Component
{
private:
    std::vector<Component*>m_vecChildren;
public:
    explicit Composite(std::string name):Component(name){};
    void add(Component* p)
    {
        m_vecChildren.emplace_back(p);
    };

    void remove(Component* p)
    {
        for (auto it = m_vecChildren.begin(); it != m_vecChildren.end(); it++) {
             if (*it == p) {
                 m_vecChildren.erase(it);
                 std::cout << m_strName << " remove: " << p->getName() << std::endl;
                 break;
             }
         }
    };

    void operation() const override {
        std::cout << "Composite: " << m_strName << std::endl;
        for (const auto& child : m_vecChildren) {
            child->operation();
        }
    }
    ~Composite()
    {
        std::vector<Component*>().swap(m_vecChildren);
        std::cout << "~Composite() " << std::endl;
    }
};
class Client
{
public:
    void doWork()
    {
        // 创建叶节点
          Component* leafNode1 = new Leaf("leafNode 1");
          Component* leafNode2 = new Leaf("leafNode 2");
          Component* leafNode3 = new Leaf("leafNode 3");

          // 创建容器子节点
          Composite* childNode1 = new Composite("childNode 1");
          Composite* childNode2 = new Composite("childNode 2");

          // 将叶节点添加到容器子节点中
          childNode1->add(leafNode1);
          childNode1->add(leafNode2);
          childNode2->add(leafNode3);

          // 将容器节点添加到根容器中
          Composite* rootNode = new Composite("rootNode");
          rootNode->add(childNode1);
          rootNode->add(childNode2);

          // 调用根容器的操作方法,将逐层遍历整个组合结构并调用每个节点的操作方法
          rootNode->operation();

          //移除节点
          std::cout << "\n" << std::endl;
          childNode1->remove(leafNode2);
          rootNode->remove(childNode2);
          std::cout << "\n" << std::endl;

          // 调用根容器的操作方法,将逐层遍历整个组合结构并调用每个节点的操作方法
          rootNode->operation();

          delete leafNode1;
          delete leafNode2;
          delete leafNode3;
          delete childNode1;
          delete childNode2;
          delete rootNode;

          leafNode1 = nullptr;
          leafNode2 = nullptr;;
          leafNode3 = nullptr;;
          childNode1 = nullptr;;
          childNode2 = nullptr;;
          rootNode = nullptr;;

    }
};
int main()
{
    Client obj;
    obj.doWork();
    return 0;
}

 程序运行结果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值