组合(Composite)模式

组合模式

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

当我们需要递归创建树状结构,并且各个节点不尽相同时,Composite模式提供了很好的方法。

举个栗子: 假设MI公司的公司结构成树状结构,下属许多分公司Filiale,分公司下有办事处Office。这些机构有都有财务部门Finance与人力资源HumanResource部门。

Composite

其中Finance 和 HumanResource 时 叶子;而Filiale, Office是Compnsite, 其抽象基类是Compnent.有对分支管理的方法。

//composite.hpp

#include <iostream>
#include <vector>
#include <algorithm>

#ifndef _DESIGN_PATTERN_COMPOSITE_COMPOSITE_HPP_
#define _DESIGN_PATTERN_COMPOSITE_COMPOSITE_HPP_

namespace design_pattern
{

class Compnent
{
public:
	virtual ~Compnent() {}
	virtual void Add(Compnent * const ) {}
	virtual void Remove(Compnent * const ) {}
	virtual Compnent * GetChild(int i) 
	{
		if (0 == vcomp_.size() || i >= vcomp_.size())
			return nullptr;
		else
			return vcomp_[i];
	}
	virtual void Operation() = 0;

protected:
  std::vector<Compnent *> vcomp_;
};

class Finance : public Compnent
{
public:
	void Operation()
	{
		std::cout << "Finance : Operation()" << std::endl;
	}
};

class HumanResource : public Compnent
{
public:
	void Operation()
	{
		std::cout << "HumanResource : Operation()" << std::endl;
	}
};

static std::string pfx = "";

class Filiale : public Compnent
{
public:
	void Add(Compnent * const ptr)
	{
		vcomp_.push_back(ptr);
	}

	void Remove(Compnent * const ptr)
	{
		std::vector<Compnent *>::iterator it = find(vcomp_.begin(), vcomp_.end(), ptr);
		if(it != vcomp_.end())
			vcomp_.erase(it);
	}


	void Operation()
	{
		std::cout << "Filiale : Operation()" << std::endl;

		std::vector<Compnent *>::iterator it = vcomp_.begin();
		while (it != vcomp_.end())
		{
			pfx.append("--");
			std::cout << pfx;
			(*it)->Operation();
			++it;
			pfx.erase(pfx.size() - 2, 2);
		}

	}
};

class Office : public Compnent
{

public:
	
	void Add(Compnent * const ptr)
	{
		vcomp_.push_back(ptr);
	}

	void Remove(Compnent * const ptr)
	{
		std::vector<Compnent *>::iterator it = find(vcomp_.begin(), vcomp_.end(), ptr);

		if (it != vcomp_.end())
			vcomp_.erase(it);
	}

	Compnent * GetChild(int idx)
	{
		return vcomp_[idx];
	}

	void Operation()
	{
		std::cout << "Office : Operation()" << std::endl;
		
		std::vector<Compnent *>::iterator it = vcomp_.begin();
	  
		while (it !=vcomp_.end())
		{
			pfx.append("--");
			std::cout << pfx;
			(*it)->Operation();
			++it;
			pfx.erase(pfx.size() - 2, 2);
		}
	}
};
}

#endif // !_DESIGN_PATTERN_COMPOSITE_COMPOSITE_HPP_

//compasite_main.cpp

#include "composite.hpp"
#include <memory>
using std::unique_ptr;
using namespace design_pattern;

int main()
{
	Filiale root;
	unique_ptr<Compnent> lf(new Finance);
	unique_ptr<Compnent> lhr(new HumanResource);
	Office of;
	root.Add(lf.get());
	root.Add(lhr.get());
	root.Add(&of);

  unique_ptr<Compnent> lf1(new Finance);
	of.Add(lf1.get());
	root.Operation();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值