文档章节

设计模式学习--组合模式

丿咖啡灬微凉
 丿咖啡灬微凉
发布于 2017/04/17 23:57
字数 1188
阅读 7
收藏 0

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


透明方式和安全方式

  透明方式,就是说在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶结点和枝结点对于外界没有区别,它们具有完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add、Remove方法的功能,所以实现它是没有意义的。

  安全模式,就是在Component接口中不去声明Add和Remove方法。那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法。不过由于不透明,所以树叶和树枝类将不具备相同的接口,客户端的调用需要做相应的判断,带来了不便。

何时使用组合模式

  需求中是体现部分与整体层次的结构时,希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。

#include <iostream>
#include <list>

using namespace std;

class Company											//公司抽象类
{
	string m_name;										//公司名和部门名
public:	
	Company(string name):m_name(name){};				//构造函数传入公司名字
	string getname(){return m_name;}					//获取名字
	virtual void Add(Company* c) = 0;					//增加公司名字或者部门名字
	virtual void Remove(Company* c) = 0;				//删除公司名字或者部门名字
	virtual void Display(int dapth) = 0;				//打印公司名字或者部门名字
	virtual void LineOfDuty() = 0;						//打印部门职责
};

class RealCompany : public Company						//具体公司类
{
	list<Company*> link; 								//链表存放各个公司
	list<Company*>::iterator it;						//链表迭代器
public:
	RealCompany(string name):Company(name){};			//构造函数传入公司名字
	
	void Add(Company* c)								//增加名字结点
	{
		link.push_back(c);
	}
	
	void Remove(Company* c)								//删除名字结点
	{
		link.remove(c);
	}
	
	void Display(int dapth)								//打印公司名字或者部门名字
	{		
		cout<<"-"<<this->getname()<<endl;
		for(it = link.begin(); it != link.end(); it++)
		{
			for(int i = 0; i < dapth; i++)
				cout<<"-";
			(*it)->Display(dapth);
		}
	}
	
	void LineOfDuty()									//打印部门职责
	{
		for(it = link.begin(); it != link.end(); it++)
		{
			(*it)->LineOfDuty();
		}
	}
};

class HRDepartmemt : public Company						//人力资源部
{
public:
	HRDepartmemt(string name):Company(name){};			//构造函数传入公司名字
	
	void Add(Company* c)								//没用到的方法
	{
		return;
	}
	
	void Remove(Company* c)								//没用到的方法
	{
		return;
	}

	void Display(int dapth)								//打印部门名字
	{
		cout<<this->getname()<<endl;
	}
	
	void LineOfDuty()									//打印部门职责
	{
		cout<<this->getname()<<"员工招聘培训管理"<<endl;
	}
};

class FinDepartmemt : public Company					//财务部
{
public:
	FinDepartmemt(string name):Company(name){};			//构造函数传入公司名字
	
	void Add(Company* c)								//没用到的方法
	{
		return;
	}
	
	void Remove(Company* c)								//没用到的方法
	{
		return;
	}
	
	void Display(int dapth)								//打印部门名字
	{
		cout<<this->getname()<<endl;
	}
	
	void LineOfDuty()									//打印部门职责
	{
		cout<<this->getname()<<"公司财务收支管理"<<endl;
	}
};

int main()
{
	RealCompany* root = new RealCompany("北京总公司");
	root->Add((new HRDepartmemt("总公司人力资源部")));
	root->Add((new FinDepartmemt("总公司财务部")));
	
	RealCompany* shanghai = new RealCompany("上海分公司");
	shanghai->Add((new HRDepartmemt("华东分公司人力资源部")));
	shanghai->Add((new FinDepartmemt("华东分公司财务部")));
	root->Add(shanghai);
	
	RealCompany* nanjing = new RealCompany("南京办事处");
	nanjing->Add((new HRDepartmemt("南京办事处人力资源部")));
	nanjing->Add((new FinDepartmemt("南京办事处财务部")));
	root->Add(nanjing);
	
	cout<<"\n结构图:"<<endl;
	root->Display(1);
	
	cout<<"\n职责:"<<endl;
	root->LineOfDuty();
	
	root->Remove(nanjing);
	
	cout<<"\n结构图:"<<endl;
	root->Display(1);
	
	cout<<"\n职责:"<<endl;
	root->LineOfDuty();
	
	return 0;
}

显示结果:


[hjf@hjf 设计模式]$ ./a.out 


结构图:
-北京总公司
-总公司人力资源部
-总公司财务部
--上海分公司
-华东分公司人力资源部
-华东分公司财务部
--南京办事处
-南京办事处人力资源部
-南京办事处财务部


职责:
总公司人力资源部员工招聘培训管理
总公司财务部公司财务收支管理
华东分公司人力资源部员工招聘培训管理
华东分公司财务部公司财务收支管理
南京办事处人力资源部员工招聘培训管理
南京办事处财务部公司财务收支管理


结构图:
-北京总公司
-总公司人力资源部
-总公司财务部
--上海分公司
-华东分公司人力资源部
-华东分公司财务部


职责:
总公司人力资源部员工招聘培训管理
总公司财务部公司财务收支管理
华东分公司人力资源部员工招聘培训管理
华东分公司财务部公司财务收支管理

本文转载自:http://blog.csdn.net/hjf161105/article/details/62082082

丿咖啡灬微凉
粉丝 1
博文 70
码字总数 0
作品 0
私信 提问
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
274
0
设计模式15——Template Method设计模式

Template Method模板方法设计模式定义一个操作中算法的骨架,将具体步骤的执行延迟到子类中实现。Java中的抽象类就是使用了模板方法设计模式。模板方法设计模式结构如下: 以文档处理为例,T...

小米米儿小
2014/01/24
202
0
EasyToLearnDesignPattern

简单上手设计模式 GITHUB:https://github.com/Fisher-Joe/EasyToLearnDesignPattern 本文旨在使用最简单的语言,最简单的代码让人学习设计模式(最起码是我) 说明: 本文的所有内容都是基于...

芝麻开门
04/19
0
0
JavaScript 的一些设计模式

设计模式的定义:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案 设计模式是前人解决某个特定场景下对而总结出来的一些解决方案。可能刚开始接触编程还没有什么经验的时候,会...

格西南
08/20
0
0
(目录)设计模式(可复用面向对象软件的基础)

本系列“设计模式”博客使用Golang语言实现算法。所谓算法是指解决一个问题的步骤,个人觉得不在于语言。小弟只是最近学习Golang,所以顺带熟练一下语法知识,别无它意。 本系列博客主要介绍...

chapin
2015/01/13
154
0

没有更多内容

加载失败,请刷新页面

加载更多

JS基础-该如何理解原型、原型链?

JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对这个...

OBKoro1
今天
7
0
高防CDN的出现是为了解决网站的哪些问题?

高防CDN是为了更好的服务网络而出现的,是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路,再反馈给用户,可以减轻用户使用过程的复杂程度。通过智能DNS解析,能让网站访问者连接到...

云漫网络Ruan
今天
14
0
OSChina 周一乱弹 —— 熟悉的味道,难道这就是恋爱的感觉

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoshiyue :好久没分享歌了分享张碧晨的单曲《今后我与自己流浪》 《今后我与自己流浪》- 张碧晨 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
3K
24
SpringBoot中 集成 redisTemplate 对 Redis 的操作(二)

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二) List 类型的操作 1、 向列表左侧添加数据 Long leftPush = redisTemplate.opsForList().leftPush("name", name); 2、 向列表右......

TcWong
今天
46
0
排序––快速排序(二)

根据排序––快速排序(一)的描述,现准备写一个快速排序的主体框架: 1、首先需要设置一个枢轴元素即setPivot(int i); 2、然后需要与枢轴元素进行比较即int comparePivot(int j); 3、最后...

FAT_mt
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部