示例问题:
一家总部在北京的大型公司,在全国几大城市设有分公司,比如上海设有华东区分部、在成都设有西南区分部,然后在一些省会城市还设有办事处,比如西南区的重庆办事处、贵阳办事处。无论是在北京总部,还是在成都西南区分部、重庆办事处等都有财务部、技术部等。总部、分部、办事处存在隶属关系,是一种树状结构,要求按照树状结构展示所有的财务部、技术部。
分析:
这是一种部分和整体的关系。成都西南区分部对于总部来说,成都西南区分部是部分,总部是整体;重庆办事处对于成都西南分区来说,重庆办事处是分部,成都西南分区是整体。而部分和整体都具有财务部、技术部等相同的功能,因此整体和部分可以一致对待。
解决方案:
Composite.h
在该文件中,实现了组织基类IOganization,及其子类CCompany(公司类(总部、分部、办事处等都为公司类))、CHRDepartment(人力资源部)、CTechDepartment(技术部)
#pragma once
#include <string>
#include <iostream>
#include <list>
#include <algorithm>
//组织基类
class IOganization
{
public:
IOganization(std::string strName)
: m_strName(strName)
{
}
virtual ~IOganization()
{
}
virtual void Add(IOganization* pOganization) = 0;
virtual void Remove(IOganization* pOganization) = 0;
virtual void DisPlay(int iDepth) = 0;
std::string m_strName;
std::list<IOganization*> m_listOganization;
};
//公司类(总部、分部、办事处等都为公司类)
class CCompany : public IOganization
{
public:
CCompany(std::string strName) : IOganization (strName)
{
}
virtual ~CCompany()
{
}
void Add(IOganization* pOganization)
{
m_listOganization.push_back(pOganization);
}
void Remove(IOganization* pOganization)
{
if (nullptr == pOganization)
{
return;
}
std::list<IOganization*>::iterator iter = std::find(m_listOganization.begin(), m_listOganization.end(), pOganization);
if (iter == m_listOganization.end())
{
m_listOganization.erase(iter);
}
}
void DisPlay(int iDepth)
{
for (size_t i = 0; i < iDepth; i++)
{
std::cout << "-";
}
std::cout << m_strName << std::endl;
for (auto pOganization : m_listOganization)
{
if (nullptr != pOganization)
{
pOganization->DisPlay(iDepth + 3);
}
}
}
};
//人力资源部
class CHRDepartment : public IOganization
{
public:
CHRDepartment(std::string strName) : IOganization(strName)
{
}
virtual ~CHRDepartment()
{
}
void Add(IOganization* pOganization)
{
}
virtual void Remove(IOganization* pOganization)
{
}
virtual void DisPlay(int iDepth)
{
for (size_t i = 0; i < iDepth; i++)
{
std::cout << "-";
}
std::cout << "人力资源部" << std::endl;
}
};
//技术部
class CTechDepartment : public IOganization
{
public:
CTechDepartment(std::string strName) : IOganization(strName)
{
}
virtual ~CTechDepartment()
{
}
void Add(IOganization* pOganization)
{
}
virtual void Remove(IOganization* pOganization)
{
}
virtual void DisPlay(int iDepth)
{
for (size_t i = 0; i < iDepth; i++)
{
std::cout << "-";
}
std::cout << "技术部" << std::endl;
}
};
main.cpp
// main.cpp : Defines the entry point for the console application.
//
#include "Composite.h"
#define DELETEMEMORY(pData) {if(nullptr != pData) {delete pData; pData = nullptr;}}
int main()
{
IOganization* pHeadquarters = new(std::nothrow) CCompany("北京总部");
IOganization* pBranchSH = new(std::nothrow) CCompany("上海华东区分部");
IOganization* pBranchCD = new(std::nothrow) CCompany("成都西南区分部");
IOganization* pOfficeNJ = new(std::nothrow) CCompany("南京办事处");
IOganization* pOfficeHF = new(std::nothrow) CCompany("合肥办事处");
IOganization* pOfficeCQ = new(std::nothrow) CCompany("重庆办事处");
IOganization* pOfficeGY = new(std::nothrow) CCompany("贵阳办事处");
IOganization* pHRDepartment = new(std::nothrow) CHRDepartment("人力资源部");
IOganization* pTechDepartment = new(std::nothrow) CTechDepartment("技术部");
//总部直属结构
if (nullptr != pHeadquarters)
{
pHeadquarters->Add(pBranchSH);
pHeadquarters->Add(pBranchCD);
pHeadquarters->Add(pHRDepartment);
pHeadquarters->Add(pTechDepartment);
}
//上海华东区分部直属结构
if (nullptr != pBranchSH)
{
pBranchSH->Add(pOfficeNJ);
pBranchSH->Add(pOfficeHF);
pBranchSH->Add(pHRDepartment);
pBranchSH->Add(pTechDepartment);
}
//成都西南区分部直属结构
if (nullptr != pBranchCD)
{
pBranchCD->Add(pOfficeCQ);
pBranchCD->Add(pOfficeGY);
pBranchCD->Add(pHRDepartment);
pBranchCD->Add(pTechDepartment);
}
//南京办事处直属结构
if (nullptr != pOfficeNJ)
{
pOfficeNJ->Add(pHRDepartment);
pOfficeNJ->Add(pTechDepartment);
}
//合肥办事处直属结构
if (nullptr != pOfficeHF)
{
pOfficeHF->Add(pHRDepartment);
pOfficeHF->Add(pTechDepartment);
}
//重庆办事处直属结构
if (nullptr != pOfficeCQ)
{
pOfficeCQ->Add(pHRDepartment);
pOfficeCQ->Add(pTechDepartment);
}
//贵阳办事处直属结构
if (nullptr != pOfficeGY)
{
pOfficeGY->Add(pHRDepartment);
pOfficeGY->Add(pTechDepartment);
}
//展示所有的组织
pHeadquarters->DisPlay(1);
//清理内存
{
DELETEMEMORY(pHeadquarters);
DELETEMEMORY(pBranchSH);
DELETEMEMORY(pBranchCD);
DELETEMEMORY(pOfficeNJ);
DELETEMEMORY(pOfficeHF);
DELETEMEMORY(pOfficeCQ);
DELETEMEMORY(pOfficeGY);
DELETEMEMORY(pHRDepartment);
DELETEMEMORY(pTechDepartment);
}
system("pause");
return 0;
}
运行结果:
组合模式的使用:
组合模式:将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式定义了包含基本对象(示例代码中的CHRDepartment(人力资源部)、CTechDepartment(技术部))和组合对象(示例代码中的CCompany(公司类(总部、分部、办事处等都为公司类)))的层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去。客户代码中,任何用到基本对象的地方都可以使用组合对象了。且由客户程序确定层级结构,可由客户程序灵活增加爱增层次或者增加每一个层里的对象。
用户不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了。组合模式让客户可以一致地使用组合结构和单个对象。
何时使用组合模式:
当发现需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象和单个对象的不同,统一地使用组合结构中的所有对象是,就应该考虑使用组合模式了。
返回目录:设计模式(C++实现)(总)
下一篇:已完结