结构型设计模式之组合模式【设计模式系列】

这篇具有很好参考价值的文章主要介绍了结构型设计模式之组合模式【设计模式系列】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

C++技能系列
Linux通信架构系列
C++高性能优化编程系列
深入理解软件架构设计系列
高级C++并发线程编程
设计模式系列

期待你的关注哦!!!
结构型设计模式之组合模式【设计模式系列】,设计模式系列,设计模式,组合模式,架构,c++,java

现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。
Now everything is for the future of dream weaving wings, let the dream fly in reality.

一、组合模式介绍

⚠️ 意图:
将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

⚠️ 主要解决:
它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

⚠️ 何时使用:
1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

⚠️ 如何解决:
树枝和叶子实现统一接口,树枝内部组合该接口。

现有一个公司需要实现一个广播的功能,用来通知给公司所有部门重要的信息。如果需要广播,那么必须通过每一个部门类的实例去调用各自部门的广播接口。通过一个抽象类来抽象出广播接口,各个部门和公司都通过继承实现抽象接口。如此实现可以将所有部门放在一个容器内,遍历实现其广播接口。如果公司不扩大,永远有这几个部门并且没有分公司的话,是没问题的。如果再要添加一个部门,就必须实现一个部门类,再修改总公司类。这明显违背了开闭原则。既然我们通过抽象类来实现了其方法,那就可以实现抽象的增加,删除,查询接口。如此一来,如果要有新的部门, 那么只需要通过调用添加接口来增加新部门, 广播的时候,只需要遍历容器中的广播接口即可。实现类图如下:

结构型设计模式之组合模式【设计模式系列】,设计模式系列,设计模式,组合模式,架构,c++,java

图1_1 组合模式类图

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 “组合对象” 的含义。

组合模式可以让客户端像修改配置文件一样简单的完成本来需要流程控制语句来完成的功能。

二、组合模式优缺点

2.1 优点

  • 简化客户端调用,实现符合开闭原则。
  • 高层模块调用简单。
  • 节点自由增加

2.2 缺点

  • 如果业务逻辑负责,则实现组合模式比较困难。

  • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

三、组合模式使用场景

适用于“整体-部分”层次的树形结构的。部分、整体场景,如树形菜单,文件、文件夹的管理。

客户端对组合对象统一的使用所有对象。

四、组合模式实现

Component.h

#ifndef COMPONENTS_H_
#define COMPONENTS_H_

#include <iostream>
#include <vector>

using namespace std;

class Components
{
public:
    Components(std::string strName):m_strName(strName){}

    virtual void Operation() = 0;
    virtual void AddSubCompany(Components* subCompany);
    virtual void DelSubCompany(Components* subCompany);
    virtual Components* GetCompanyByIndex(int iIndex);

protected:
    std::string m_strName;
};

class ConcreteCompany : public Components
{
public:
    ConcreteCompany(std::string strName):Components(strName){}
    ~ConcreteCompany();

    virtual void Operation();
    virtual void AddSubCompany(Components* subCompany);
    virtual void DelSubCompany(Components* subCompany);
    virtual Components* GetCompanyByIndex(int iIndex);
private:
    std::vector<Components*> m_vecSubItem;
};

class FinanceDepartment : public Components
{
public:
    FinanceDepartment(std::string strName):Components(strName){}

    virtual void Operation();
};

class HRDepartment : public Components
{
public:
    HRDepartment(std::string strName):Components(strName){}

    virtual void Operation();
};

#endif

Component.cpp

#include "Company.h"
#include <algorithm>

#ifndef SAFE_DELETE
#define SAFE_DELETE(p){if((p) != NULL){delete (p); (p) = NULL;}}
#endif

void Components::AddSubCompany( Components* subCompany )
{
    cout << "Have no realized!" << endl;
}

void Components::DelSubCompany( Components* subCompany )
{
    cout << "Have no realized!" << endl;
}

Components* Components::GetCompanyByIndex( int iIndex )
{
    cout << "Have no realized!" << endl;
    return NULL;
}

//******************//
//**CentralCompany**//
//******************//

ConcreteCompany::~ConcreteCompany()
{
    std::for_each(m_vecSubItem.begin(),m_vecSubItem.end(),[&](Components* item)
    {
        SAFE_DELETE(item);
    });
}

void ConcreteCompany::Operation()
{
    std::for_each(m_vecSubItem.begin(),m_vecSubItem.end(),[&](Components* item)
    {
        item->Operation();
    });
}

void ConcreteCompany::AddSubCompany( Components* subCompany )
{
    if (subCompany != NULL)
    {
        m_vecSubItem.push_back(subCompany);
    }
}

void ConcreteCompany::DelSubCompany( Components* subCompany )
{
    for (auto it = m_vecSubItem.begin(); it != m_vecSubItem.end(); ++it)
    {
        if ((*it) == subCompany)
        {
            m_vecSubItem.erase(it);
            SAFE_DELETE(subCompany);
            break;
        }
    }
}

Components* ConcreteCompany::GetCompanyByIndex( int iIndex )
{
    if (iIndex < 0 || iIndex > m_vecSubItem.size())
    {
        return NULL;
    }
    return m_vecSubItem[iIndex];
}

void FinanceDepartment::Operation()
{
    cout << m_strName.c_str() << endl;
}

void HRDepartment::Operation()
{
    cout << m_strName.c_str() << endl;
}

main.cpp

#include <iostream>
#include "Company.h"

using namespace std;

int main()
{
    Components* Central = new ConcreteCompany("Central Company");
    Central->AddSubCompany(new FinanceDepartment("Central Finance Department"));
    Central->AddSubCompany(new HRDepartment("Central HR Department"));

    Components* Xian = new ConcreteCompany("Xi'An Company");
    Xian->AddSubCompany(new FinanceDepartment("Xi'An Finance Department"));
    Xian->AddSubCompany(new HRDepartment("Xi'An HR Department"));

    Central->AddSubCompany(Xian);
    Central->Operation();

    cout << "<<<<<>>>>>" << endl;
    Central->DelSubCompany(Xian);
    Central->Operation();

    return 0;
}

输出:文章来源地址https://www.toymoban.com/news/detail-606813.html

Central Finance Department

Central HR Department

Xi’An Finance Department

Xi’An HR Department

<<<<<>>>>>

Central Finance Department

Central HR Department

到了这里,关于结构型设计模式之组合模式【设计模式系列】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java设计模式之结构型-组合模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、基本实现 4.2、菜单遍历  五、总结  组合模式(Composite Pattern)又叫部分-整体模式,它通过将对象组合成树形结构来表示“整体-部分”的层次关系,允许用户统一单个对象和组合对象的处理逻辑。 角色 描述

    2024年02月16日
    浏览(50)
  • 结构型设计模式之代理模式【设计模式系列】

    C++技能系列 Linux通信架构系列 C++高性能优化编程系列 深入理解软件架构设计系列 高级C++并发线程编程 设计模式系列 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reali

    2024年02月16日
    浏览(51)
  • 设计模式--------结构型模式

    结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构

    2024年02月13日
    浏览(49)
  • 结构型设计模式——桥接模式

    桥接模式(Bridge pattern): 使用桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。 桥接模式 (Bridge) 是一种结构型设计模式, 可将 抽象 部分与 实现 部分 分离 ,使它们都可以独立的变化。如果一个系统需要在构件的抽象化角色和具体化角色之间增加更

    2024年02月07日
    浏览(49)
  • 设计模式之结构型模式

    本文已收录于专栏 《设计模式》   大话设计模式主要分为三部分,第一部分是创建型模式,第二部分是结构型模式,第三部分是行为型模式。至于为什么要分为这三部分,我的理解是创建型是用于创建对象的而结构型是发生在类与类之间的关系是比较宏观的,比如说组合

    2024年02月11日
    浏览(40)
  • 结构型设计模式——外观模式

    有句话说这个世界就是个草台班子,只不过排面做的好看而已,里面都是一包糠。这句话来形容外观模式非常准确,外观模式又叫门面模式,顾名思义一个系统我不管你里面有多复杂有多少屎山代码,我只要求你提供的接口好用,简单就行,即门面要有排面!用专业的话讲是

    2024年01月22日
    浏览(46)
  • 设计模式结构型——外观模式

    目录 什么是外观模式 外观模式的实现 外观模式角色 外观模式举例 外观模式类图 外观模式代码实现 外观模式的特点 优点 缺点 注意事项 应用场景 总结         外观模式(Facade Pattern):又叫作门面模式,归属于结构型模式。外观模式定义了提供了定义了一个统一的高层

    2024年02月16日
    浏览(58)
  • 设计模式之桥接模式【结构型模式】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博

    2024年01月25日
    浏览(50)
  • 设计模式之结构型模式---代理模式

    代理模式是一种结构型设计模式,它为目标对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用,客户端通过代理类与目标对象进行交互,而不是直接与目标对象进行交互。 代理模式的应用场景非常广泛,包括但不限于以下几种情

    2024年04月17日
    浏览(42)
  • 设计模式-结构型模式之桥接模式

    设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案: 第一种设计方案是为每一种形状都提供一套各种颜色的版本。 第二种设计方案是根据实际需要对形状和

    2023年04月18日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包