c++ 组合模式(composite)
原文地址:http://www.cnblogs.com/jiese/p/3168844.html
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。
基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。
用户不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合二写一些选择判断语句了。
组合模式让客户可以一致地使用组合结构和单个对象。
抽象基类:
1)Component:为组合中的对象声明接口,声明了类共有接口的缺省行为(如这里的Add,Remove,GetChild函数),声明一个接口函数可以访问Component的子组件.
接口函数:
1)Component::Operatation:定义了各个组件共有的行为接口,由各个组件的具体实现.
2)Component::Add添加一个子组件
3)Component::Remove::删除一个子组件.
4)Component::GetChild:获得子组件的指针.
说明:
Component模式是为解决组件之间的递归组合提供了解决的办法,它主要分为两个派生类:
1)、Leaf是叶子结点,也就是不含有子组件的结点
2)、Composite是含有子组件的类.
举一个例子来说明这个模式,在UI的设计中,最基本的控件是诸如Button、Edit这样的控件,相当于是这里的Leaf组件,而比较复杂的控件
比如Panel则可也看做是由这些基本的组件组合起来的控件,相当于这里的Composite,它们之间有一些行为含义是相同的,比如在控件上作一个点
击,移动操作等等的,这些都可以定义为抽象基类中的接口虚函数,由各个派生类去实现之,这些都会有的行为就是这里的Operation函数,而添加、删除
等进行组件组合的操作只有非叶子结点才可能有,所以虚拟基类中只是提供接口而且默认的实现是什么都不做。
代码如下:
composite.h
#ifndef _COMPOSITE_H_
#define _COMPOSITE_H_ #include <vector> using namespace std; /*
Component抽象基类,为组合中的对象声明接口,声明了类共有接口的缺省行为(如这里的Add,Remove,GetChild函数),
声明一个接口函数可以访问Component的子组件.
*/
class Component
{
public:
//纯虚函数,只提供接口,没有默认的实现
virtual void Operation()=; // 虚函数,提供接口,有默认的实现就是什么都不做
virtual void Add(Component*);
virtual void Remove(Component*);
virtual Component* GetChild(int index);
virtual ~Component();
protected:
Component();
}; //Leaf是叶子结点,也就是不含有子组件的结点类,所以不用实现Add、Remove、GetChild等方法
class Leaf:public Component
{
public:
//只实现Operation接口
virtual void Operation();
Leaf();
~Leaf();
}; //Composite:含有子组件的类
class Composite:public Component
{
public:
Composite();
~Composite();
//实现所有接口
void Operation();
void Add(Component*);
void Remove(Component*);
Component* GetChild(int index);
private:
//这里采用vector来保存子组件
vector<Component*> m_ComVec;
};
#endif
composite.cpp
#include "Composite.h"
#include <iostream> using namespace std; Component::Component()
{} Component::~Component()
{} void Component::Add(Component* com)
{
cout << "add" << endl;
} void Component::Remove(Component* com)
{
} void Component::Operation()
{
cout << "Component::Operation" << endl;
} Component* Component::GetChild(int index)
{
return NULL;
} Leaf::Leaf()
{} Leaf::~Leaf()
{} void Leaf::Operation()
{
cout<< "Leaf::Operation" <<endl;
} Composite::Composite()
{
} Composite::~Composite()
{} void Composite::Add(Component* com)
{
this->m_ComVec.push_back(com);
} void Composite::Remove(Component* com)
{
//this->m_ComVec.erase(com);
} void Composite::Operation()
{
cout << "Composite::Operation" << endl;
vector<Component*>::iterator iter = this->m_ComVec.begin();
for(;iter!= this->m_ComVec.end();iter++)
{
(*iter)->Operation();
}
} Component* Composite::GetChild(int index)
{
if(index < || index > this->m_ComVec.size())
{
return NULL;
}
return this->m_ComVec[index];
}
main.cpp
#include "composite.h"
#include <iostream> using namespace std; int main()
{
/*
不管是叶子Leaf还是Composite对象pRoot、pCom都实现了Operation接口,所以可以一致对待,直接调用Operation()
体现了“使得用户对单个对象和组合对象的使用具有一致性。”
*/
Composite* pRoot = new Composite(); //组合对象添加叶子节点
pRoot->Add(new Leaf()); Leaf* pLeaf1 = new Leaf();
Leaf* pLeaf2 = new Leaf(); //这里的叶子再添加叶子是没有意义的。
//由于叶子与组合对象继承了相同的接口,所以语法上是对的,实际上什么也没做(继承自基类Component的Add方法)。
//叶子节点只实现了Operation方法,其他Add、Remove、GetChild都继承自基类,没有实际意义。
pLeaf1->Add(pLeaf2);
pLeaf1->Remove(pLeaf2);
//执行叶子Operation操作
pLeaf1->Operation(); //组合对象实现了基类Component的所有接口,所以可以做各种操作(Add、Remove、GetChild、Operation)。
Composite* pCom = new Composite();
//组合对象添加叶子节点
pCom->Add(pLeaf1);
//组合对象添加叶子节点
pCom->Add(pLeaf2);
//执行组合对象Operation操作
pCom->Operation(); //组合对象添加组合对象
pRoot->Add(pCom); //执行组合对象Operation操作
pRoot->Operation(); //Component* cp = pCom->GetChild(0);
//cp->Operation(); //pCom->Remove(pLeaf1); system("pause");
return ;
}
c++ 组合模式(composite)的更多相关文章
- 组合模式/composite模式/对象结构型模式
组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...
- 浅谈设计模式--组合模式(Composite Pattern)
组合模式(Composite Pattern) 组合模式,有时候又叫部分-整体结构(part-whole hierarchy),使得用户对单个对象和对一组对象的使用具有一致性.简单来说,就是可以像使用 ...
- 二十四种设计模式:组合模式(Composite Pattern)
组合模式(Composite Pattern) 介绍将对象组合成树形结构以表示"部分-整体"的层次结构.它使得客户对单个对象和复合对象的使用具有一致性.示例有一个Message实体 ...
- 设计模式(七)组合模式Composite(结构型)
设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...
- 乐在其中设计模式(C#) - 组合模式(Composite Pattern)
原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...
- 【设计模式】组合模式 Composite Pattern
树形结构是软件行业很常见的一种结构,几乎随处可见, 比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...
- 设计模式 - 组合模式(composite pattern) 迭代器(iterator) 具体解释
组合模式(composite pattern) 迭代器(iterator) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考组合模式(composit ...
- 设计模式系列之组合模式(Composite Pattern)——树形结构的处理
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 设计模式--组合模式Composite(结构型)
一.概念 组合模式允许你将对象组合成树形结构来表现"整体/部分"层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 二.UML图 1.Component(对象接口),定义 ...
- C#设计模式——组合模式(Composite Pattern)
一.概述 在软件开发中,我们往往会遇上类似树形结构的对象体系.即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在.比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点.在设计这 ...
随机推荐
- mysql 存储过程查询语句
可以用 命令"show PROCEDURE status"查看所有的存储过程或检索系统表"mysql.proc"来查询已有的存储过程.例如:用show PROC ...
- 【学习】JennyHui学英语 - Bingo口语笔记
学习素材:Bingo说美语 Hold系列 如何吞音 表示“无所谓” Pick系列 英式和美式英语的发音区别 表示“迷茫” Break系列 爆破音发音技巧 表示“不相信” 常见词汇的缩读 表示“身体抱恙 ...
- 高级C/C++编译技术之读书笔记(五)之动态库版本控制
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- BigDecimal的用法
一.简介 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更 ...
- Bootstrap-table学习笔记(二)——前后端分页模糊查询
在使用过程中,一边看文档一边做,遇到了一些困难的地方,在此记录一下,顺便做个总结: 1,前端分页 2,后端分页 3,模糊查询 前端分页相当简单,在我添加了2w条测试数据的时候打开的很流畅,没有卡顿. ...
- Xcode7 修改项目名完全攻略
1.先把整个工程文件夹名改为新的工程名. 2 .将旧项目文件夹和Tests文件名夹修改为新的名称,修改后如下图所示 3.右击 ,选择“show content package”(中文:显示包内容),看 ...
- linux 本地账号密码无法登陆(shell可以登录),一直返回 登陆的login界面
今天我在我虚拟机测试的时候遇到了一个问题.登陆centos一直是返回login,账号和密码没错,我也换了两个用户. 1.问题描述 我正常的输入用户名和密码 错误提示截图:返回登陆界面,我重新试了另外的 ...
- maven命令行创建web项目报错:java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils
早上一上班就想新建一个web项目玩玩,没想到一敲命令创建就失败了,真是出师不利.各种折腾无果,当然我也可以用eclipse直接创建的,就是不甘心被这破问题给耍了.刚刚才发现问题原因,这个结果我也是醉了 ...
- erlang的dict和maps模块
erlang在r17以后增加了map这个数据结构,在之前,类似map的需求用dict模块来实现,这里直接贴一下相关的操作 dict D = dict:new(). D1 = dict:store(k1 ...
- POJ3020(最小边覆盖)
Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8924 Accepted: 4428 ...