天天看点

大话设计模式19----组合模式大话设计模式

大话设计模式

1 组合模式(Composite)结构图

大话设计模式19----组合模式大话设计模式

2 对组合模式的一些解释

概念:将对象组合成树形结构以表示“ 部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。如:Word文档中对文字的处理,即可以处理单个字又可以处理多个字、甚至是对整个文档的处理;再比如说总公司和各个分公司在职务功能都类似,但是子公司包含于总公司之中,如下图的结构:

大话设计模式19----组合模式大话设计模式

Component类:

class Component
{
protected:
	string name;

public:
	Component(string name)
	{
		this->name = name;
	}

	//通过Add和Remove来实现增加树叶或者树枝的功能
	virtual void Add(Component *c){};
	virtual void Remove(Component *c){};

	virtual void Display(int depth){};
};
           

Leaf类:

class Leaf :public Component
{
public:
	Leaf(string name) :Component(name){}

	void Add(Component *c) override
	{
		cout << "叶子结点实现该接口的意义不大,因为叶子结点不会增加叶子或者树枝,但是这么做可以" ;
		cout << "消除叶子结点和树枝结点对象在抽象层次的区别,使它们具有完全一致的接口,这种方式称之为透明方式" << endl;
	}

	void Remove(Component *c) override
	{
		cout << "同上" << endl;
	}

	void Display(int depth) override
	{
		cout << "显示层次和名字" << endl;
	}
};
           

Composite类:

class  Composite :public Component
{
private:
	vector<Component> vec;//一个子对象集合用来存储其下属的树枝节点和叶结点

public:
	Composite(string name) :Component(name){}

	void Add(Component *c) override
	{
		vec.push_back(c);
	}

	void Remove(Component *c) override
	{
		vec.Delete(c);//vector中没有这种方法,这里只是形象的代表删除该叶结点或者枝节点
	}

	void Display(int depth) override
	{
		cout << "循环递归显示该结点及其下属结点" << endl;
	}
};
           

Client.h类

int main()
{
	Composite *root = new Composite("root");//生成根节点root,根上长出两夜LeafA和LeafB
	root->Add(new Leaf("Leaf A"));
	root->Add(new Leaf("Leaf B"));

	Composite *comp = new Composite("Composite X");//跟上长出分支Composite X
	comp->Add(new Leaf("Leaf XA"));//该枝上长出两个叶子结点
	comp->Add(new Leaf("Leaf XB"));

	root->Add(comp);

	.......依次类推;

	return 0;
}
           

Leaf(叶子)中也可以不实现Add和Remove方法,因为实现他们没有意义,这种方式成为 安全方式,不过由于不透明,所以树叶树枝将不具有相同的接口,从而使得客户端的调用就需要判断一下;着这种角度来讲,这种方式就不如 透明方式了。

使用场景:

  • 需求中体现部分与整体层次的结构的时候;
  • 希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时。

优点:

  • 组合模式定义了包含(人力资源部和财务部这些)基本对象和(分公司、办事处等)组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了;
  • 组合模式让客户可以一致的使用组合结构和单个对象。

3 C++实现

3.1 代码结构图

大话设计模式19----组合模式大话设计模式

3.2 C++源代码

公司类Component.h

#ifndef _Company_H_
#define _COMPONENT_H

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

using std::endl;
using std::cout;
using std::string;
using std::vector;

class Company
{
protected:
	string name;

public:
	Company(string name)
	{
		this->name = name;
	}

	virtual string getName(){ return name; }//返回公司名字
	virtual void Add(Company *c){};//增加
	virtual void Remove(Company *c){};//移除
	virtual void Display(int depth){};//显示
	virtual void LineOfDuty(){};//履行职责,不同的部门需要履行不同的职责
};

//创建具体的公司
class ConcreteCompany :public Company
{
private:
	vector<Company *> *vec;

public:
	ConcreteCompany(string name) :Company(name)
	{
		vec = new vector<Company *>();
	}

	//增加析构函数,防止内存泄漏
	~ConcreteCompany()
	{
		for (auto it = vec->begin(); it != vec->end(); ++it)
		{
			delete (*it);
		}

		delete vec;
	}

	string getName() override
	{
		return this->name;
	}

	//增加叶子结点
	void Add(Company *c) override
	{
		vec->push_back(c);
	}

	//删除叶子结点
	void Remove(Company *c) override
	{
		for (auto it = vec->begin(); it != vec->end(); ++it)
		{
			if (c->getName() == ((*it)->getName()))
			{
				vec->erase(it);
				break;
			}
		}
	}

	//打印
	void Display(int depth) override
	{
		for (int i = 0; i < depth; ++i)
			cout << "-";
		cout << name << endl;

		for (auto it = vec->begin(); it != vec->end(); ++it)
			(*it)->Display(depth + 4);
	}

	//职责
	void LineOfDuty() override
	{
		for (auto it = vec->begin(); it != vec->end(); ++it)
			(*it)->LineOfDuty();
	}
};

//人力资源部
class HRDepartment :public Company
{
public:
	HRDepartment(string name) :Company(name){}

	void Add(Company *c) override{}
	void Remove(Company *c) override{}
	void Display(int depth) override
	{
		for (int i = 0; i < depth; ++i)
			cout << "-";
		cout << name << endl;
	}

	void LineOfDuty() override
	{
		cout << name << " 负责招聘培训管理" << endl;
	}

	string getName() override
	{
		return this->name;
	}
};

//财务部
class FinanceDepartment :public Company
{
public:
	FinanceDepartment(string name) :Company(name){}

	void Add(Company *c) override{}
	void Remove(Company *c) override{}
	void Display(int depth) override
	{
		for (int i = 0; i < depth; ++i)
			cout << "-";
		cout << name << endl;
	}

	void LineOfDuty() override
	{
		cout << name << " 公司财务收支管理" << endl;
	}

	string getName() override
	{
		return this->name;
	}
};
#endif
           

客户端代码:

#include"Component.h"

int main()
{
	ConcreteCompany *root = new ConcreteCompany("北京总公司");
	root->Add(new HRDepartment("总公司人力资源部"));
	root->Add(new FinanceDepartment("总公司财务部"));

	ConcreteCompany *comp = new ConcreteCompany("上海华东分公司");
	comp->Add(new HRDepartment("上海华东分公司人力资源部"));
	comp->Add(new FinanceDepartment("上海华东分公司财务部"));
	root->Add(comp);

	ConcreteCompany *comp2 = new ConcreteCompany("南京办事处");
	comp2->Add(new HRDepartment("南京办事处人力资源部"));
	comp2->Add(new FinanceDepartment("南京办事处财务部"));
	comp->Add(comp2);

	ConcreteCompany *comp3 = new ConcreteCompany("杭州办事处");
	comp3->Add(new HRDepartment("杭州办事处人力资源部"));
	comp3->Add(new FinanceDepartment("杭州办事处财务部"));
	comp->Add(comp3);

	cout << "结构图" << endl;
	root->Display(1);
	cout << endl << endl;

	cout << "职责" << endl;
	root->LineOfDuty();
	cout << endl;

	delete root;//剩下的由析构函数自动释放
	system("pause");
	return 0;
}
           

运行结果:

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


职责
总公司人力资源部 负责招聘培训管理
总公司财务部 公司财务收支管理
上海华东分公司人力资源部 负责招聘培训管理
上海华东分公司财务部 公司财务收支管理
南京办事处人力资源部 负责招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 负责招聘培训管理
杭州办事处财务部 公司财务收支管理

请按任意键继续. . .
           

继续阅读