组合模式
将对象组合成树形结构表示 “部分-整体” 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
当我们需要递归创建树状结构,并且各个节点不尽相同时,Composite模式提供了很好的方法。
举个栗子: 假设MI公司的公司结构成树状结构,下属许多分公司Filiale,分公司下有办事处Office。这些机构有都有财务部门Finance与人力资源HumanResource部门。
其中Finance 和 HumanResource 时 叶子;而Filiale, Office是Compnsite, 其抽象基类是Compnent.有对分支管理的方法。
#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;
}