zoukankan      html  css  js  c++  java
  • 组合模式(c++实现)

    组合模式

    定义

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

    动机

    当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合对象结构中的所有对象时,就应该考虑用组合模式了。

    UML类图

    场景拆解

    以一个大型公司为需求背景,组织我们的代码。一个北京总公司,下面有郑州和西安两个分公司。然后每个公司不管是总公司还是分公司都有自己的人力资源部,IT部和市场部。

    源码实现

    • component.h
    #ifndef COMPONENT_H
    #define COMPONENT_H
    #include <QList>
    
    class Component
    {
    public:
        Component(QString name);
        virtual ~Component();
        virtual void add(Component* com, int depth = 0) = 0;
        virtual void remove(Component* com) = 0;
        virtual void display() = 0;
        virtual void LineOfDuty() = 0;
    
        QString name();
        void setDepth(int depth);
        int depth();
    private:
        QString         m_Name;
        int                 m_Depth;
    };
    
    class ConcreteCompany : public Component
    {
    public:
        ConcreteCompany(QString name);
        virtual ~ConcreteCompany();
        virtual void add(Component* com, int depth = 0);
        virtual void remove(Component* com);
        virtual void display();
        virtual void LineOfDuty();
    private:
        QList<Component*> m_ChildCom;
    };
    
    class HumanResource : public Component
    {
    public:
        HumanResource(QString name);
        virtual ~HumanResource();
        virtual void add(Component* com, int depth = 0);
        virtual void remove(Component* com);
         virtual void display();
        virtual void LineOfDuty();
    };
    
    class IT : public Component
    {
    public:
        IT(QString name);
        virtual ~IT();
        virtual void add(Component* com, int depth = 0);
        virtual void remove(Component* com);
         virtual void display();
        virtual void LineOfDuty();
    };
    
    class Marketing : public Component
    {
    public:
        Marketing(QString name);
        virtual ~Marketing();
        virtual void add(Component* com, int depth = 0);
        virtual void remove(Component* com);
         virtual void display();
        virtual void LineOfDuty();
    };
    #endif // COMPONENT_H
    
    
    • component.cpp
    /************************************
        * @brief	: 安排一下故事背景:有一个王者农药全国总公司在深圳,现在想要在全国开办事处
        * 1.北京办事处- 招聘部,研发部,市场部
        * 2.郑州办事处- 招聘部,研发部,市场部
        * 3.西安办事处- 招聘部,研发部,市场部
        * and so on...
        * @author	:   wzx
        * @date	:   2020-05-11
        * @project	:  Composite
    *************************************/
    #include <QDebug>
    #include "component.h"
    
    #define DELETEOBJECT(x) if(x) { delete x; x = nullptr; }
    
    Component::Component(QString name):m_Name(name) {}
    
    Component::~Component(){}
    
    QString Component::name()
    {
        return m_Name;
    }
    
    void Component::setDepth(int depth)
    {
        m_Depth = depth;
    }
    
    int Component::depth()
    {
        return m_Depth;
    }
    
    ConcreteCompany::ConcreteCompany(QString name)
        : Component(name)
    {
    
    }
    
    ConcreteCompany::~ConcreteCompany()
    {
        for(auto com : m_ChildCom)
        {
            DELETEOBJECT(com);
        }
        m_ChildCom.clear();
    }
    
    void ConcreteCompany::add(Component* com, int depth)
    {
        com->setDepth(depth);
        m_ChildCom.append(com);
    }
    
    void ConcreteCompany:: remove(Component* com)
    {
        m_ChildCom.removeOne(com);
    }
    
    void ConcreteCompany::display()
    {
        QString str;
        for(int n = 0; n < depth(); ++n)
            str += "--";
        qDebug() << qPrintable(str)  <<  (name());
        for(auto com : m_ChildCom)
        {
            com->display();
        }
    }
    
    void ConcreteCompany::LineOfDuty()
    {
    
    }
    
    HumanResource::HumanResource(QString name)
        : Component(name)
    {
    
    }
    
    HumanResource::~HumanResource()
    {
    
    }
    
    void HumanResource::add(Component* com, int depth)
    {
        com->setDepth(depth);
    }
    
    void HumanResource::remove(Component* com)
    {
    
    }
    
    void HumanResource::display()
    {
        QString str;
        for(int n = 0; n < depth(); ++n)
            str += "--";
        qDebug() << qPrintable(str)  <<  (name());
    }
    
    void HumanResource::LineOfDuty()
    {
        qDebug() << "人力资源部,负责招聘";
    }
    
    IT::IT(QString name)
        : Component(name)
    {
    
    }
    
    IT::~IT()
    {
    
    }
    
    void IT::add(Component* com, int depth)
    {
        com->setDepth(depth);
    }
    
    void IT::remove(Component* com)
    {
    
    }
    
    void IT::display()
    {
        QString str;
        for(int n = 0; n < depth(); ++n)
            str += "--";
        qDebug() << qPrintable(str)  <<  (name());
    }
    
    void IT::LineOfDuty()
    {
        qDebug() << "IT部门,负责写代码";
    }
    
    Marketing::Marketing(QString name)
        : Component(name)
    {
    
    }
    
    Marketing::~Marketing()
    {
    
    }
    
    void Marketing::add(Component* com, int depth)
    {
        com->setDepth(depth);
    }
    
    void Marketing::remove(Component* com)
    {
    
    }
    
    void Marketing::display()
    {
        QString str;
        for(int n = 0; n < depth(); ++n)
            str += "--";
        qDebug() << qPrintable(str)  <<  name();
    }
    
    void Marketing::LineOfDuty()
    {
        qDebug() << "市场部门,负责市场推广";
    }
    
    
    • main.cpp
    #include <QCoreApplication>
    #include <QDebug>
    #include "component.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Component* root = new ConcreteCompany("北京总部");
        root->setDepth(0);
        root->add(new HumanResource("人力资源部门"), 1);
        root->add(new IT("IT部门"), 1);
        root->add(new Marketing("市场部门"), 1);
    
        Component* zz = new ConcreteCompany("郑州办事处");
        zz->add(new HumanResource("人力资源部门"), 2);
        zz->add(new IT("IT部门"), 2);
        zz->add(new Marketing("市场部门"), 2);
        root->add(zz, 1);
    
        Component* xa = new ConcreteCompany("西安办事处");
        xa->add(new HumanResource("人力资源部门"), 2);
        xa->add(new IT("IT部门"), 2);
        xa->add(new Marketing("市场部门"), 2);
        root->add(xa, 1);
    
        root->display();
        return a.exec();
    }
    
    
    • 运行结果

    "北京总部"

    -- "人力资源部门"

    -- "IT部门"

    -- "市场部门"

    -- "郑州办事处"

    ---- "人力资源部门"

    ---- "IT部门"

    ---- "市场部门"

    -- "西安办事处"

    ---- "人力资源部门"

    ---- "IT部门"

    ---- "市场部门"

    优点

    组合模式定义了包含基本对象和组合对象的类层次结构。基本对象可以组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。

    缺点

    参考《大化设计模式》

  • 相关阅读:
    OpenStack Trail 部署文档(二)基础服务部署
    OpenStack Trail 部署文档(一)环境规划
    OpenStack Trail 部署文档
    配置kubectl在Mac(本地)远程连接Kubernetes集群
    elasticsearch*3 + Es-Head + kibana Docker集群
    Flex 布局教程:语法篇
    PHP 数组 array_merge 和 数组 + 加号操作的区别
    Redis分布式锁
    Mysql中Exists和In的使用
    让PHP7达到最高性能的几个Tips
  • 原文地址:https://www.cnblogs.com/wzxNote/p/12874358.html
Copyright © 2011-2022 走看看