设计模式之组合模式-一个人的力量是有限的,组合更强大!

一、组合模式的概念

组合模式,又叫部分整体模式,属于结构型模式,是用于把一组相似的对象当作一个单一的对象,
它依据树形结构来组合对象,用来表示“部分-整体”层次,创建一个对象组的树形结构,通过一个对象可以访问整个对象树。

二、组合模式使用场景

1、用来表示对象的“部分-整体”层次结构时可以使用组合模式。
2、希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象。

三、组合模式构建方法

1、抽象构件类

提供客户端可以调用的抽象接口,为叶子构件和容器构件对象定义接口。

2、容器构件类

容器构件包含子节点,它包含了一个存储子节点容器,实现了抽象构件中定义的接口,包括访问及管理子构件的接口,可以递归调用其子节点的业务方法。

3、叶子构件类

叶子节点没有子节点,它实现了 抽象构件中定义的行为,但是对于访问及管理子构件的接口,需要通过异常等方式进行处理。

四、组合模式的示例

// ComponentPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

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

#define DELETE_PTR(p) {if(p!=nullptr){delete (p); (p)=nullptr;}}

using namespace std;

// 抽象构件类
class ComponentCompany
{
public:
	ComponentCompany(string strName)
	{
		m_strName = strName;
	}
	virtual ~ComponentCompany(){}
	virtual void add(ComponentCompany *pComponentCompany) = 0;
	virtual void remove(ComponentCompany *pComponentCompanyp) = 0;
	virtual ComponentCompany *getChild(int index) = 0;
	virtual void showChild() = 0;

protected:
	string m_strName;
};

// 容器构件类
class CompositeCompany : public ComponentCompany
{
public:
	CompositeCompany(string strName) : ComponentCompany(strName){}

	virtual ~CompositeCompany() 
	{
		while (!m_comElemsVector.empty())
		{
			vector<ComponentCompany *>::iterator it = m_comElemsVector.begin();
			DELETE_PTR(*it);
			m_comElemsVector.erase(it);
		}
	}

	void add(ComponentCompany *pComponentCompany)
	{
		m_comElemsVector.push_back(pComponentCompany);
	}

	void remove(ComponentCompany *pComponentCompany)
	{
		for (auto *iter : m_comElemsVector)
		{
			if (iter == pComponentCompany)
			{
				DELETE_PTR(pComponentCompany);
				break;
			}
		}
	}

	ComponentCompany *getChild(int index)
	{
		if (index >= m_comElemsVector.size())
		{
			return nullptr;
		}
		return m_comElemsVector.at(index);
	}

	void showChild()
	{
		cout << m_strName << endl;
		for (auto *iter : m_comElemsVector)
		{
			iter->showChild();
		}
	}

private:
	vector<ComponentCompany *> m_comElemsVector;
};

// 叶子构件类
class LeafDepart : public ComponentCompany
{
public:
	LeafDepart(string strName) : ComponentCompany(strName) {}

	virtual ~LeafDepart(){}

	void add(ComponentCompany *pComponentCompany)
	{
		cout << "LeafDepart Node Can't add a leaf!" << endl;
	}

	void remove(ComponentCompany *pComponentCompany)
	{
		cout << "Can't remove a leaf from LeafDepart Node!" << endl;
	}

	ComponentCompany *getChild(int index)
	{
		cout << "Can't getChild a leaf from LeafDepart Node!" << endl;;
		return nullptr;
		
	}

	void showChild()
	{
		cout << m_strName << endl;;
	}
};

int main()
{
	cout << "-------------组合模式--------------" << endl;
	// 总公司
	ComponentCompany *pHeadCompany = new CompositeCompany("-总公司");
	// 子公司
	ComponentCompany *pBranchCompany = new CompositeCompany("-------子公司");
	pBranchCompany->add(new LeafDepart("-------------子公司研发部"));
	pBranchCompany->add(new LeafDepart("-------------子公司产品部"));
	pBranchCompany->add(new LeafDepart("-------------子公司测试部"));
	pBranchCompany->add(new LeafDepart("-------------子公司网络部"));

	pHeadCompany->add(pBranchCompany);
	pHeadCompany->add(new LeafDepart("-------总公司研发部"));
	pHeadCompany->add(new LeafDepart("-------总公司产品部"));
	pHeadCompany->add(new LeafDepart("-------总公司测试部"));
	pHeadCompany->add(new LeafDepart("-------总公司网络部"));

	pHeadCompany->showChild();

	//DELETE_PTR(pBranchCompany);调用下面的删除时,会自动在析构函数中删除该指针
	DELETE_PTR(pHeadCompany);

    std::cout << "Hello World!\n";
	getchar();
}

运行结果:
在这里插入图片描述

五、组合模式的优缺点

优点:

1、可以方便的实现树形结构,为树形结构提供一种灵活的处理方案。
2、单个对象和组合对象具有一致性,简化客户端调用接口。
3、清楚定义了“部分-整体”的层次结构,方便对整个层次的管理与控制。
4、方便扩展增加容器结构和叶子结构,无需对现有的类做任何修改。

缺点:

1、太过复杂的业务规则,使用组合模式难度比较大、设计抽象比较困难,有时候很多方法并不适用于所有的叶子构件类,需要做异常处理。

能力有限,如有错误,多多指教。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值