设计模式学习--组合模式

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


透明方式和安全方式

  透明方式,就是说在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶结点和枝结点对于外界没有区别,它们具有完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add、Remove方法的功能,所以实现它是没有意义的。

  安全模式,就是在Component接口中不去声明Add和Remove方法。那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法。不过由于不透明,所以树叶和树枝类将不具备相同的接口,客户端的调用需要做相应的判断,带来了不便。

何时使用组合模式

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

#include <iostream>
#include <list>

using namespace std;

class Company											//公司抽象类
{
	string m_name;										//公司名和部门名
public:	
	Company(string name):m_name(name){};				//构造函数传入公司名字
	string getname(){return m_name;}					//获取名字
	virtual void Add(Company* c) = 0;					//增加公司名字或者部门名字
	virtual void Remove(Company* c) = 0;				//删除公司名字或者部门名字
	virtual void Display(int dapth) = 0;				//打印公司名字或者部门名字
	virtual void LineOfDuty() = 0;						//打印部门职责
};

class RealCompany : public Company						//具体公司类
{
	list<Company*> link; 								//链表存放各个公司
	list<Company*>::iterator it;						//链表迭代器
public:
	RealCompany(string name):Company(name){};			//构造函数传入公司名字
	
	void Add(Company* c)								//增加名字结点
	{
		link.push_back(c);
	}
	
	void Remove(Company* c)								//删除名字结点
	{
		link.remove(c);
	}
	
	void Display(int dapth)								//打印公司名字或者部门名字
	{		
		cout<<"-"<<this->getname()<<endl;
		for(it = link.begin(); it != link.end(); it++)
		{
			for(int i = 0; i < dapth; i++)
				cout<<"-";
			(*it)->Display(dapth);
		}
	}
	
	void LineOfDuty()									//打印部门职责
	{
		for(it = link.begin(); it != link.end(); it++)
		{
			(*it)->LineOfDuty();
		}
	}
};

class HRDepartmemt : public Company						//人力资源部
{
public:
	HRDepartmemt(string name):Company(name){};			//构造函数传入公司名字
	
	void Add(Company* c)								//没用到的方法
	{
		return;
	}
	
	void Remove(Company* c)								//没用到的方法
	{
		return;
	}

	void Display(int dapth)								//打印部门名字
	{
		cout<<this->getname()<<endl;
	}
	
	void LineOfDuty()									//打印部门职责
	{
		cout<<this->getname()<<"员工招聘培训管理"<<endl;
	}
};

class FinDepartmemt : public Company					//财务部
{
public:
	FinDepartmemt(string name):Company(name){};			//构造函数传入公司名字
	
	void Add(Company* c)								//没用到的方法
	{
		return;
	}
	
	void Remove(Company* c)								//没用到的方法
	{
		return;
	}
	
	void Display(int dapth)								//打印部门名字
	{
		cout<<this->getname()<<endl;
	}
	
	void LineOfDuty()									//打印部门职责
	{
		cout<<this->getname()<<"公司财务收支管理"<<endl;
	}
};

int main()
{
	RealCompany* root = new RealCompany("北京总公司");
	root->Add((new HRDepartmemt("总公司人力资源部")));
	root->Add((new FinDepartmemt("总公司财务部")));
	
	RealCompany* shanghai = new RealCompany("上海分公司");
	shanghai->Add((new HRDepartmemt("华东分公司人力资源部")));
	shanghai->Add((new FinDepartmemt("华东分公司财务部")));
	root->Add(shanghai);
	
	RealCompany* nanjing = new RealCompany("南京办事处");
	nanjing->Add((new HRDepartmemt("南京办事处人力资源部")));
	nanjing->Add((new FinDepartmemt("南京办事处财务部")));
	root->Add(nanjing);
	
	cout<<"\n结构图:"<<endl;
	root->Display(1);
	
	cout<<"\n职责:"<<endl;
	root->LineOfDuty();
	
	root->Remove(nanjing);
	
	cout<<"\n结构图:"<<endl;
	root->Display(1);
	
	cout<<"\n职责:"<<endl;
	root->LineOfDuty();
	
	return 0;
}

显示结果:


[hjf@hjf 设计模式]$ ./a.out 


结构图:
-北京总公司
-总公司人力资源部
-总公司财务部
--上海分公司
-华东分公司人力资源部
-华东分公司财务部
--南京办事处
-南京办事处人力资源部
-南京办事处财务部


职责:
总公司人力资源部员工招聘培训管理
总公司财务部公司财务收支管理
华东分公司人力资源部员工招聘培训管理
华东分公司财务部公司财务收支管理
南京办事处人力资源部员工招聘培训管理
南京办事处财务部公司财务收支管理


结构图:
-北京总公司
-总公司人力资源部
-总公司财务部
--上海分公司
-华东分公司人力资源部
-华东分公司财务部


职责:
总公司人力资源部员工招聘培训管理
总公司财务部公司财务收支管理
华东分公司人力资源部员工招聘培训管理
华东分公司财务部公司财务收支管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值