C++设计模式---组合模式

1、介绍

        组合模式(Composite)是一种结构型设计模式,也被称为部分-整体模式。它将复杂对象视为由多个简单对象(称为“组件”)组成的树形结构,这些组件能够共享相同的行为。每个组件都可能包含一个或多个子组件,而不需要了解子组件的具体类型。

在组合模式中,有三个关键角色:

        (1)组件(Composite):这个抽象类或接口定义了所有组件都具有的公共行为。它通常有一个或多个方法来访问其子组件,并且可以包含一个指向子组件的指针数组。

        (2)具体组件(Leaf):这是没有子组件的组件,它们直接实现了组件接口。这些是组合模式的叶子节点,不包含其他元素。

        (3)复合组件(Composite):这是有子组件的组件,它们除了实现组件接口外,还负责维护子组件的列表,以及调用相应的方法对它们进行操作。

组合模式的优点:

        (1)支持动态扩展和灵活的层次结构。

        (2)降低组件间的耦合度,使得代码更易于理解和维护。

        (3)可以统一处理所有类型的组件,无论是简单的还是复杂的。

2、示例

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

// 抽象的组件类Element 描写全部部件共同拥有的行为
class Element
{
public:
    Element(const std::string& name): m_name(name){}
    virtual ~Element(){}
    virtual void eat() = 0;
    virtual void add(Element *) = 0;
    virtual void remove(Element *) = 0;
    virtual const std::string& getName()
	{
		return m_name;
	}
protected:
    std::string m_name;
};

// 具体组件类,叶子构件 Apple类
class Apple : public Element
{
public:
    Apple(const std::string& name): Element(name){}
	virtual ~Apple()
    {
        std::cout << "~Apple()" << std::endl;
    }
    void eat()
    {
        std::cout << "eat fruit type is apple" << std::endl;
    }
     void add(Element *pcomt){}
     void remove(Element *pcomt){}
};
 
// 具体组件类,叶子构件 Banana类
class Banana : public Element
{
public:
    Banana(const std::string& name): Element(name){}
	virtual ~Banana()
    {
        std::cout << "~Banana()" << std::endl;
    }
    void eat()
    {
        std::cout << "eat fruit type is banana " << std::endl;
    }
    void add(Element *pcomt){}
    void remove(Element *pcomt){}
};
 
// 具体组件类,叶子构件 Pear类
class Pear : public Element
{
public:
    Pear(const std::string& name): Element(name){}
	virtual ~Pear()
    {
        std::cout << "~Pear()" << std::endl;
    }
    void eat()
    {
        std::cout << "eat fruit type is pear" << std::endl;
    }
    void add(Element *pcomt){}
    void remove(Element *pcomt){}
};
 
// 复合组件类 容器构件类 PlateComposite水果盘
class PlateComposite : public Element
{
public:
    PlateComposite(const std::string& name): Element(name){}
    virtual ~PlateComposite()
	{
		std::cout << "~PlateComposite()" << std::endl;
        std::vector<Element *>::iterator it = _vecComp.begin();
        while (it != _vecComp.end()) 
        {
            if (*it != NULL)
            {
                std::cout << "----delete " << (*it)->getName() << "----" << std::endl;
                delete *it;
                *it = NULL;
            }
            _vecComp.erase(it); 
            it = _vecComp.begin();
        }
	}
	 
	void eat()
    {
        for(auto iter : _vecComp){
            iter ->eat();
        }
    }
	 
    void add(Element *pcomt)
    {
        _vecComp.push_back(pcomt);
    }
    void remove(Element *pcomt)
    {
        for (std::vector<Element *>::iterator it = _vecComp.begin(); it != _vecComp.end(); ++it)
        {
            if ((*it)->getName() == pcomt->getName())
            {
                if (*it != NULL)
                {
                    delete *it;
                    *it = NULL;
                }
                _vecComp.erase(it);
                break;
            }
        }
    }
private:
    std::vector<Element *> _vecComp;
};
 
int main() 
{ 
    Element *obj1 = new Apple("apple");
    Element *obj2 = new Banana("banana");
    Element *plate1 = new PlateComposite("zuhe_1");
    plate1->add(obj1);
    plate1->add(obj2);
    plate1->eat();
    std::cout << "-----------------------------------------------" << std::endl;

    Element *obj3 = new Pear("pear");
    Element *plate2 = new PlateComposite("zuhe_2");
    plate2->add(obj3);
    plate2->eat();
    std::cout << "-----------------------------------------------" << std::endl;

    plate1->add(plate2);   // 将组合zuhe_2添加到组合zuhe_1中
    plate1->eat();
    std::cout << "-----------------------------------------------" << std::endl;

    plate1->remove(obj1);
    plate1->eat();
    std::cout << "-----------------------------------------------" << std::endl;
    // delete obj1;
    // delete obj2;

    if(nullptr != plate1){
        delete plate1;
        plate1 = nullptr;
    }
    return 0; 
} 

结果:

eat fruit type is apple
eat fruit type is banana 
-----------------------------------------------
eat fruit type is pear
-----------------------------------------------
eat fruit type is apple
eat fruit type is banana 
eat fruit type is pear
-----------------------------------------------
~Apple()
eat fruit type is banana 
eat fruit type is pear
-----------------------------------------------
~PlateComposite()
----delete banana----
~Banana()
----delete zuhe_2----
~PlateComposite()
----delete pear----
~Pear()

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值