组合模式

  组合模式,是为了解决整体和部分的一致对待的问题而产生的,要求这个整体与部分有一致的操作或行为。部分和整体都继承与一个公共的抽象类,这样,外部使用它们时是一致的,不用管是整体还是部分,使用一个方法即可遍历整体中的所有的部分。就像一个树形结构一样。

适用性:

  常用于组织结构,产品结构之类的整体和部分的结构。例如图形由很多直线构成,直线由点构成,这就是整体和部分的关系。如果采用组合模式,只需要使用一个draw方法即可按遍历的方式画出所有的点,最终呈现出来的就是图形。

优点:

  隐藏了整体和部分,让外部依赖于抽象,简化了代码。

缺点:

  1.要求必须有一致的行为。

  2.处于同一个Composite的Leaf与Leaf之间难以传递数据。

代码实现1

  比如一个集团公司,它有一个母公司,下设很多家子公司。不管是母公司还是子公司,都有各自直属的财务部、人力资源部、销售部等。对于母公司来说,不论是子公司,还是直属的财务部、人力资源部,都是它的部门。整个公司的部门拓扑图就是一个树形结构。

#include <iostream>
#include <list>
#include <string> using namespace std; class Company
{
public:
Company(string name) { m_name = name; }
virtual ~Company(){}
virtual void Add(Company *pCom){}
virtual void Show(int depth) {}
protected:
string m_name;
};
//具体公司
class ConcreteCompany : public Company
{
public:
ConcreteCompany(string name): Company(name) {}
virtual ~ConcreteCompany() {}
void Add(Company *pCom) { m_listCompany.push_back(pCom); } //位于树的中间,可以增加子树
void Show(int depth)
{
for(int i = ;i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
list<Company *>::iterator iter=m_listCompany.begin();
for(; iter != m_listCompany.end(); iter++) //显示下层结点
(*iter)->Show(depth + );
}
private:
list<Company *> m_listCompany;
};
//具体的部门,财务部
class FinanceDepartment : public Company
{
public:
FinanceDepartment(string name):Company(name){}
virtual ~FinanceDepartment() {}
virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点
{
for(int i = ; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
};
//具体的部门,人力资源部
class HRDepartment :public Company
{
public:
HRDepartment(string name):Company(name){}
virtual ~HRDepartment() {}
virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点
{
for(int i = ; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
}; int main()
{
Company *root = new ConcreteCompany("总公司");
Company *leaf1=new FinanceDepartment("财务部");
Company *leaf2=new HRDepartment("人力资源部");
root->Add(leaf1);
root->Add(leaf2); //分公司A
Company *mid1 = new ConcreteCompany("分公司A");
Company *leaf3=new FinanceDepartment("财务部");
Company *leaf4=new HRDepartment("人力资源部");
mid1->Add(leaf3);
mid1->Add(leaf4);
root->Add(mid1);
//分公司B
Company *mid2=new ConcreteCompany("分公司B");
FinanceDepartment *leaf5=new FinanceDepartment("财务部");
HRDepartment *leaf6=new HRDepartment("人力资源部");
mid2->Add(leaf5);
mid2->Add(leaf6);
root->Add(mid2);
root->Show(); delete leaf1; delete leaf2;
delete leaf3; delete leaf4;
delete leaf5; delete leaf6;
delete mid1; delete mid2;
delete root;
return ;
}

结果:

总公司
--财务部
--人力资源部
--分公司A
----财务部
----人力资源部
--分公司B
----财务部
----人力资源部
请按任意键继续. . .

上面的实现方式有缺点,就是内存的释放不好,需要客户自己动手,非常不方便。有待改进,比较好的做法是让ConcreteCompany类来释放。因为所有的指针都是存在ConcreteCompany类的链表中。C++的麻烦,没有垃圾回收机制。

代码实现2

  下面示例有两种情况,add函数对于Leaf来说是没有必要的,所以可以在Leaf的add实现中什么都不写。还一种办法就是将add方法挪到Composite中,让外部使用Composite和Component。但这样的缺点就是暴露了Composite,客户端必须知道Composite才能完成操作,好处Leaf不用产生多余的方法了。

#include <iostream>
#include <vector>
using namespace std; class Component
{
public:
Component(){};
virtual ~Component(){}; virtual void operation() = ;
}; class Leaf: public Component
{
public:
Leaf(){};
~Leaf(){}; void operation() { cout << "Operation leaf" << endl; }
}; class Composite: public Component
{
public:
Composite(){};
~Composite(){}; void add(Component* c) { m_leafs.push_back(c); }
void operation()
{
cout << "Operation Composite" << endl;
vector<Component*>::iterator comIter = m_leafs.begin();
for (; comIter != m_leafs.end(); comIter++)
{
(*comIter)->operation();
}
} private:
vector<Component*> m_leafs;
}; int main()
{
Component* leaf1 = new Leaf();
Component* leaf2 = new Leaf(); Composite* composite1 = new Composite();
composite1->add(leaf1);
composite1->add(leaf2); Composite* composite2 = new Composite();
composite2->add(composite1); composite2->operation();
return ;
}

结果:

Operation Composite
Operation Composite
Operation leaf
Operation leaf
请按任意键继续. . .

参考 : http://blog.csdn.net/wuzhekai1985/article/details/6667564

设计模式 --> (8)组合模式的更多相关文章

  1. C#设计模式(10)——组合模式(Composite Pattern)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

  2. c++设计模式15 --组合模式

    今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...

  3. 乐在其中设计模式(C#) - 组合模式(Composite Pattern)

    原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...

  4. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  5. C#设计模式(10)——组合模式(Composite Pattern)(转)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

  6. C#设计模式:组合模式(Composite Pattern)

    一,C#设计模式:组合模式(Composite Pattern) using System; using System.Collections.Generic; using System.Linq; ...

  7. 【GOF23设计模式】组合模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_组合模式.树状结构.杀毒软件架构.JUnite底层架构.常见开发场景 package com.test.composite ...

  8. 设计模式:组合模式(Composite)

    定   义:将对象组合树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象使用具有一致性. 结构图: Component类: abstract class Component ...

  9. [设计模式] 8 组合模式 Composite

    DP书上给出的定义:将对象组合成树形结构以表示“部分-整体”的层次结构.组合使得用户对单个对象和组合对象的使用具有一致性.注意两个字“树形”.这种树形结构在现实生活中随处可见,比如一个集团公司,它有一 ...

  10. 再起航,我的学习笔记之JavaScript设计模式15(组合模式)

    组合模式 组合模式(Composite): 又称部分-整体模式,将对象组合成树形结构以表示"部分整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 如果有一个 ...

随机推荐

  1. HTML5之Canvas画圆形

    HTML5之Canvas画圆形 1.设计源码 <!DOCTYPE html> <head> <meta charset="utf-8" /> & ...

  2. 小程序for循环中通过index实现单个点击事件

    <!--xml--> <view class='content3-list' wx:for="{{listItems}}" > <view class ...

  3. 配置Tomcat线程参数maxThreads、acceptCount

    一.配置Tomcat/conf/server.xml修改配置 <Connector port="8080" protocol="org.apache.coyote. ...

  4. 【BZOJ3930】选数(莫比乌斯反演,杜教筛)

    [BZOJ3930]选数(莫比乌斯反演,杜教筛) 题面 给定\(n,K,L,R\) 问从\(L-R\)中选出\(n\)个数,使得他们\(gcd=K\)的方案数 题解 这样想,既然\(gcd=K\),首 ...

  5. WC2006水管局长(加强)

    倒过来就变成了加边 然后就直接LCT # include <stdio.h> # include <stdlib.h> # include <iostream> # ...

  6. [BZOJ1046] [HAOI2007] 上升序列 (dp)

    Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ...

  7. Vue-路由配置和使用步骤整理

    介绍 路由:控制组件之间的跳转,不会实现请求.不用页面刷新,直接跳转-切换组件>>> 安装 本地环境安装路由插件vue-router:    cnpm install vue-rou ...

  8. centos7.2 配置内网ntp服务器进行时间同步

    (一)修改/etc/ntp.conf 配置文件,注意红色部分,其他部分不需要改  ########################################################### ...

  9. Type Archive for required library: 'C:/Users/EuphemiaShaw/.m2/repository/org/apache/hadoop/hadoop-hdfs/2.6.5/hadoop-hdfs-2.6.5.jar' in project 'mapreduce' cannot be read or is not a valid ZIP file

    error: Description Resource Path Location Type Archive for required library: 'C:/Users/EuphemiaShaw/ ...

  10. Python爬虫获取异步加载站点pexels并下载图片(Python爬虫实战3)

    1. 异步加载爬虫 对于静态页面爬虫很容易获取到站点的数据内容,然而静态页面需要全量加载站点的所有数据,对于网站的访问和带宽是巨大的挑战,对于高并发和大访问访问量的站点来说,需要使用AJAX相关的技术 ...