设计模式---组合模式(C++实现)

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。


意图

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


解决问题

它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念

       客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。


如何解决


树枝和叶子实现统一的接口,树枝内部结构组合该接口


优点

1.高层模块调用简单

2.节点自由增加

缺点

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



C++实现


上图,是一个公司的组织结构图,总部下面有多个子公司,同时总部也有各个部门,子公司下面有多个部门。


UML类图:


Component:
1.为组合中的对象声明接口;
2.在适当的情况下,实现所有类共有接口的缺省行为;
3.声明一个接口用于访问和管理Component的子组件。
Leaf:
1.在组合中表示叶节点对象,叶节点没有子节点;
2.在组合中定义叶节点的行为。
Composite:
1.定义有子部件的那些部件的行为;
2.存储子部件。
Client:
1.通过Component接口操作组合部件的对象。


Code:

//组合模式Composite Pattern

//抽象的部件类描述将来所有部件共有的行为
class Component 
{
protected:
	string m_strComponent;
public :
	Component(string _name)
		:m_strComponent(_name)
	{}
	virtual ~Component()
	{}
	virtual void Operation() = 0;
	virtual void Add(Component* com) = 0;
	virtual void Remove(Component* com) = 0;
	virtual Component* Getchild(int index) = 0;
	virtual  string  getName()
	{
		return m_strComponent;
	}
	virtual void Print() = 0;
};

class Leaf : public Component //树叶结构
{
public:
	Leaf(string name)
		:Component(name)
	{}
	void Operation()
	{
		cout <<"name : " << m_strComponent << endl;
	}

	void Add(Component* com)
	{}
	void Remove(Component* com)
	{}
	Component *GetChild(int index)
	{
		return NULL;
	}
	void Print()
	{}
};

class Composite : public Component  //树枝结构
{
private:
	vector<Component *>  m_vecComp;
public:
	Composite(string name)
		:Component(name)
	{}
	~Composite()
	{
		vector<Component*>::iterator it = m_vecComp.begin();
		while (it != m_vecComp.end())
		{
			if (*it != NULL)
			{
				cout << "---delete" << (*it)->getName() + "---" << endl;
				delete *it;
				*it = NULL;
			}
			m_vecComp.erase(it);
			it = m_vecComp.begin();
		}
	}
	void Operation()
	{
		cout << "我是 " << m_strComponent << endl;
	}
	void Add(Component* com)
	{
		m_vecComp.push_back(com);
	}

	void Remove(Component* com)
	{
		for (vector<Component*>::iterator it = m_vecComp.begin(); it != m_vecComp.end();++it)
		{
			if ((*it)->getName() == com->getName())
			{
				if (*it != NULL)
				{
					delete *it;
					*it = NULL;
				}
				m_vecComp.erase(it);
				break;
			}
		}
	}
	Component*  Getchild(int index)
	{
		if ((size_t)index > m_vecComp.size())
			return NULL;
		return m_vecComp[index -1];
	}

	void Print()
	{
		for (vector<Component*>::iterator it = m_vecComp.begin(); it != m_vecComp.end(); ++it)
		{
			cout <<(*it)->getName() << endl;
		}
	}
};


客户端:


int test_Composite() //组合模式
{
	Component* pNode = new Composite("北京总部 ");
	Component * pNodeHr = new Composite("北京人事部");
	Component * pNode1 = new Composite("上海分公司");
	Component * pNode2 = new Composite("西安分公司");
	Component * pNode3 = new Composite("成都分公司");
	pNode->Add(pNodeHr);
	pNode->Add(pNode1);
	pNode->Add(pNode2);
	pNode->Add(pNode3);
	pNode->Print();

	Component* pNode1_Hr = new Composite("上海人事部 ");
	Component* pNode1_zj = new Composite("上海质检部 ");
	Component* pNode1_kf = new Composite("上海开发部 ");
	Component* pNode1_xs = new Composite("上海销售部 ");
	pNode1->Add(pNode1_Hr);
	pNode1->Add(pNode1_kf);
	pNode1->Add(pNode1_xs);
	pNode1->Add(pNode1_zj);
	pNode1->Print();
	//关闭上海质检部
	pNode1->Remove(pNode1_zj);
	if (pNode != NULL)
	{
		delete pNode;
		pNode = NULL;
	}
	system("pause");
	return 0;
}


使用场景

1.你想表示对象的部分-整体层次结构;
2.希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

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



总结

通过上面的简单讲解,我们知道了,组合模式意图是通过整体与局部之间的关系,通过树形结构的形式进行组织复杂对象,屏蔽对象内部的细节,对外展现统一的方式来操作对象,是我们处理更复杂对象的一个手段和方式。现在再结合上面的代码,想想文章开头提出的公司OA系统如何进行设计。



参考:

http://www.jb51.net/article/55878.htm




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值