设计模式(C++实现)(二十五)——组合模式

示例问题:

一家总部在北京的大型公司,在全国几大城市设有分公司,比如上海设有华东区分部、在成都设有西南区分部,然后在一些省会城市还设有办事处,比如西南区的重庆办事处、贵阳办事处。无论是在北京总部,还是在成都西南区分部、重庆办事处等都有财务部、技术部等。总部、分部、办事处存在隶属关系,是一种树状结构,要求按照树状结构展示所有的财务部、技术部。

分析:

这是一种部分和整体的关系。成都西南区分部对于总部来说,成都西南区分部是部分,总部是整体;重庆办事处对于成都西南分区来说,重庆办事处是分部,成都西南分区是整体。而部分和整体都具有财务部、技术部等相同的功能,因此整体和部分可以一致对待。

解决方案:

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++实现)(总)

上一篇:设计模式(C++实现)(二十四)——解释器模式

下一篇:已完结

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值