天天看点

【C++】大话设计模式C++实现,组合模式Composite

//《大话数据结构》一书中实例代码使用C#,这里用C++实现一遍

//组合模式
//分公司是总公司的一部分,但是总公司的部门可以复用于分公司
//整体和部分可以被一致对待

//总公司是根结点,分公司是子结点,部门是叶子
//将对象组合成树形结构以表示“部分-整体”的层次结构
//组合模式使得用户对单个对象和组合对象的使用具有一致性

//透明方式
//安全方式

#pragma once
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

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

//抽象组织类(总公司、分公司、办事处、部门都以组织统一对待,透明方式)
class Organization {
protected:
	string name;
public:
	Organization(string n = "")
		:name(n)
	{}
public:
	string getName() { return name; }

	virtual void add(Organization * o) = 0;
	virtual void remove(Organization * o) = 0;
	virtual void display(int depth) = 0;
	virtual void lineOfDuty() = 0; //履行职责,不同组织作出不同行为
};



class Company :public Organization {
private:
	vector<Organization*> children;

public:
	Company(string n = "")
		:Organization(n)
	{}

public:
	virtual void add(Organization * o) {
		children.push_back(o);
	}
	virtual void remove(Organization* o) {
		auto iter = std::remove(children.begin(), children.end(), o);
		children.erase(iter, children.end());
	}
	virtual void display(int depth) {
		cout << string(depth, '-') + name << endl;
		for (auto & c : children)
			c->display(depth+2);
	}
	virtual void lineOfDuty() {
		for (auto & c : children)
			c->lineOfDuty();
	}
};


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

public:
	virtual void lineOfDuty() {
		cout << "负责员工的招聘培训管理" << name << endl;
	}
};

//财务部
class FinanceDepartment :public Company {
public:
	FinanceDepartment(string n = "财务部")
		:Company(n)
	{}

public:
	virtual void lineOfDuty() {
		cout << "公司财务收支管理" << name << endl;
	}
};






	//组合模式
	cout << endl << "组合模式" << endl;
	Company root("北京总公司");
	root.add(new HRDepartment());
	root.add(new FinanceDepartment());

	Company cp1("上海分公司");
	cp1.add(new HRDepartment());
	cp1.add(new FinanceDepartment());
	root.add(&cp1);

	Company cp2("广东分公司");
	cp2.add(new HRDepartment());
	cp2.add(new FinanceDepartment());
	root.add(&cp2);

	root.display(1);
	cout << endl;
	cp2.display(1);