组合模式
装饰者模式属于结构型的设计模式,其特点是需要体现部分与整体的层次结构, 该结构类似于树状结构。
组合模式包括透明方式和安全方式。其中在透明方式中,部分的对象接口与整体的对象接口完全一致,方便用户使用,但问题在于树状结构的叶子节点部分接口不能使用。而在安全方式中,部分的对象接口与整体的对象接口不完全一致,因此用户使用时需要额外的判断。
代码
此处以大话设计模式中的公司与各个部门的关系作为组合模式的说明,此处实现的是透明方式。
C++代码
文件结构:
—include
——Company.h
——ConcreteCompany.h
——HRDepartment.h
——FinanceDepartment.h
—src
——Company.cpp
——ConcreteCompany.cpp
——HRDepartment.cpp
——FinanceDepartment.cpp
——main.cpp
代码如下:
—include/Company.h
#ifndef _COMPANY_H_
#define _COMPANY_H_
#include<string>
#include<memory>
class Company
{
public:
Company(const std::string& str);
virtual ~Company();
virtual void Add(const std::shared_ptr<Company> company)=0;
virtual void Remove(const std::shared_ptr<Company> company)=0;
virtual void Display(int depth) const =0;
virtual void LineOfDuty() const =0;
protected:
std::string name;
};
#endif
—include/ConcreteCompany.h
#ifndef _CONCRETECOMPANY_H_
#define _CONCRETECOMPANY_H_
#include<string>
#include<memory>
#include<list>
#include"Company.h"
class ConcreteCompany:public Company
{
public:
ConcreteCompany(const std::string& str);
~ConcreteCompany();
void Add(const std::shared_ptr<Company> company);
void Remove(const std::shared_ptr<Company> company);
void Display(int depth) const;
void LineOfDuty() const;
private:
std::list<std::shared_ptr<Company> > listCompany;
};
#endif
—include/HRDepartment.h
#ifndef _HRDEPARTMENT_H_
#define _HRDEPARTMENT_H_
#include<string>
#include<memory>
#include"Company.h"
class HRDepartment:public Company
{
public:
HRDepartment(const std::string& str);
~HRDepartment();
void Add(const std::shared_ptr<Company> company);
void Remove(const std::shared_ptr<Company> company);
void Display(int depth) const;
void LineOfDuty() const;
};
#endif
—include/FinanceDepartment.h
#ifndef _FINANCEDEPARTMENT_H_
#define _FINANCEDEPARTMENT_H_
#include<string>
#include<memory>
#include"Company.h"
class FinanceDepartment:public Company
{
public:
FinanceDepartment(const std::string& str);
~FinanceDepartment();
void Add(const std::shared_ptr<Company> company);
void Remove(const std::shared_ptr<Company> company);
void Display(int depth) const;
void LineOfDuty() const;
};
#endif
—src/Company.cpp
#include"Company.h"
Company::Company(const std::string& str):name(str)
{
;
}
Company::~Company()
{
;
}
—src/ConcreteCompany.cpp
#include"ConcreteCompany.h"
#include<string>
#include<list>
#include<iostream>
using namespace std;
ConcreteCompany::ConcreteCompany(const string& str):Company(str)
{
;
}
ConcreteCompany::~ConcreteCompany()
{
;
}
void ConcreteCompany::Add(const shared_ptr<Company> company)
{
listCompany.push_back(company);
}
void ConcreteCompany::Remove(const shared_ptr<Company> company)
{
listCompany.remove(company);
}
void ConcreteCompany::Display(int depth) const
{
for(int i=0;i<depth;++i)
{
cout<<"-";
}
cout<<name<<endl;
for(auto it=listCompany.begin();it!=listCompany.end();++it)
{
(*it)->Display(depth+2);
}
}
void ConcreteCompany::LineOfDuty() const
{
for(auto it=listCompany.begin();it!=listCompany.end();++it)
{
(*it)->LineOfDuty();
}
}
—src/HRDepartment.cpp
#include"HRDepartment.h"
#include<iostream>
#include<string>
using namespace std;
HRDepartment::HRDepartment(const string& str):Company(str)
{
;
}
HRDepartment::~HRDepartment()
{
;
}
void HRDepartment::Add(const shared_ptr<Company> company)
{
cout<<"HRDepartment do not add any company!!!"<<endl;
}
void HRDepartment::Remove(const shared_ptr<Company> company)
{
cout<<"HRDepartment do not remove any company!!!"<<endl;
}
void HRDepartment::Display(int depth) const
{
for(int i=0;i<depth;++i)
{
cout<<"-";
}
cout<<name<<endl;
}
void HRDepartment::LineOfDuty() const
{
cout<<name<<" "<<"公司人力资源管理"<<endl;
}
—src/FinanceDepartment.cpp
#include"FinanceDepartment.h"
#include<iostream>
#include<string>
#include<memory>
using namespace std;
FinanceDepartment::FinanceDepartment(const string& str):Company(str)
{
;
}
FinanceDepartment::~FinanceDepartment()
{
;
}
void FinanceDepartment::Add(const shared_ptr<Company> company)
{
cout<<"FinanceDepartment do not add any company!!!"<<endl;
}
void FinanceDepartment::Remove(const shared_ptr<Company> company)
{
cout<<"FinanceDepartment do not remove any company!!!"<<endl;
}
void FinanceDepartment::Display(int depth) const
{
for(int i=0;i<depth;++i)
{
cout<<"-";
}
cout<<name<<endl;
}
void FinanceDepartment::LineOfDuty() const
{
cout<<name<<" "<<"公司财务管理"<<endl;
}
—src/main.cpp
#include<iostream>
#include<memory>
#include"ConcreteCompany.h"
#include"HRDepartment.h"
#include"FinanceDepartment.h"
using namespace std;
int main()
{
shared_ptr<Company> mainCompany = make_shared<ConcreteCompany>("广东总公司");
shared_ptr<Company> mainHR = make_shared<HRDepartment>("广东总公司人力资源部");
shared_ptr<Company> mainFin = make_shared<FinanceDepartment>("广东总公司财务部");
mainCompany->Add(mainHR);
mainCompany->Add(mainFin);
shared_ptr<Company> auxCompany = make_shared<ConcreteCompany>("广州分公司");
shared_ptr<Company> auxHR = make_shared<HRDepartment>("广州分公司人力资源部");
shared_ptr<Company> auxFin = make_shared<FinanceDepartment>("广州分公司财务部");
auxCompany->Add(auxHR);
auxCompany->Add(auxFin);
mainCompany->Add(auxCompany);
cout<<"公司基本情况:"<<endl;
mainCompany->Display(1);
cout<<"各部门的职能:"<<endl;
mainCompany->LineOfDuty();
auxCompany->Remove(auxHR);
cout<<"调整后的公司基本情况:"<<endl;
mainCompany->Display(1);
cout<<"各部门的职能:"<<endl;
mainCompany->LineOfDuty();
return 0;
}
补充:在C++中使用STL的容器如vector,list等,容器的元素不能是const shared_ptr<T> ptr,因为const shared_ptr<T> ptr与T * const ptr类似,但const的指针是不能变成void指针的,因此会编译错误。
Python代码
文件结构:
—Company.py
代码如下:
# -*- coding:utf-8 -*-
class Company:
def __init__(self, str):
self._name = str
def Add(self, company):
pass
def Remove(self, company):
pass
def Display(self, depth):
pass
def LineOfDuty(self):
pass
class ConcreteCompany(Company):
def __init__(self, str):
Company.__init__(self, str)
self.__listCompany = []
def Add(self, company):
self.__listCompany.append(company)
def Remove(self, company):
self.__listCompany.remove(company)
def Display(self, depth):
str = "-"*depth
str = str + self._name
print str
for element in self.__listCompany:
element.Display(depth+2)
def LineOfDuty(self):
for element in self.__listCompany:
element.LineOfDuty()
class HRDepartment(Company):
def __init__(self, str):
Company.__init__(self, str)
def Add(self, company):
print "HRDepartment do not add any company"
def Remove(self, company):
print "HRDepartment do not remove any company"
def Display(self, depth):
str = "-"*depth
str = str + self._name
print str
def LineOfDuty(self):
print "%s %s"%(self._name, "公司人力资源管理")
class FinanceDepartment(Company):
def __init__(self, str):
Company.__init__(self, str)
def Add(self, company):
print "FinanceDepartment do not add any company"
def Remove(self, company):
print "FinanceDepartment do not remove any company"
def Display(self, depth):
str = "-"*depth
str = str + self._name
print str
def LineOfDuty(self):
print "%s %s"%(self._name, "公司财务管理")
if "__main__" == __name__:
mainCompany = ConcreteCompany("广东总公司")
mainHR = HRDepartment("广东总公司人力资源部")
mainFin = FinanceDepartment("广东总公司财务部")
mainCompany.Add(mainHR)
mainCompany.Add(mainFin)
auxCompany = ConcreteCompany("广州分公司")
auxHR = HRDepartment("广州分公司人力资源部")
auxFin = FinanceDepartment("广州分公司财务部")
auxCompany.Add(auxHR)
auxCompany.Add(auxFin)
mainCompany.Add(auxCompany)
print "公司基本情况:"
mainCompany.Display(1)
print "各部门的职能:"
mainCompany.LineOfDuty()
auxCompany.Remove(auxFin)
print "调整后的公司基本情况:"
mainCompany.Display(1)
print "各部门职能:"
mainCompany.LineOfDuty()