组合模式

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

适用性:

  常用于组织结构,产品结构之类的整体和部分的结构。例如图形由很多直线构成,直线由点构成,这就是整体和部分的关系。如果采用组合模式,只需要使用一个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. CSS3之background-clip

    1.属性简介 background-clip:padding|border|content|text|!important 2.兼容性 (1)IE6.7.8不兼容 (2)火狐3.0以上兼容 (3)Ch ...

  2. 导出CSV格式文件,用Excel打开乱码的解决办法

    导出CSV格式文件,用Excel打开乱码的解决办法 1.治标不治本的办法 将导出CSV数据文件用记事本打开,然后另存为"ANSI"编码格式,再用Excel打开,乱码解决. 但是,这 ...

  3. ioctl,unlocked_ioctl 处理方法

    kernel 2.6.35 及之前的版本中struct file_operations 一共有3个ioctl : ioctl,unlocked_ioctl和compat_ioctl 现在只有unloc ...

  4. Indent Guides for Visual Studio 代码格式化收缩插件

    代码格式化收缩插件 下载地址:http://indentguide.codeplex.com/releases/view/110312 更多关注付义方技术博客:http://blog.csdn.net ...

  5. .Net+SQL Server企业应用性能优化笔记—精确查找瓶颈

    首先我们需要部署一个测试环境,将Web项目的源代码拷到测试环境Web服务器IIS上,使得可以直接通过IE访问我们的网站.SQL Server环境可以部署在同一台机器上,条件允许的话有专门的数据库测试服 ...

  6. px单位html5响应式方案

    移动端h5响应式方案最近这几年用得最多的最多的就是rem方案了.这个需要计算根元素的font-size来实现响应式. 但这种方案也有一个缺点,那就是font-size不为整数的时候一些字体使用rem单 ...

  7. android界面设计之布局管理

    谈到android界面设计,各种布局样式不得不提!传统的布局方式有6种,我们会一一介绍. 在android studio2.2版本之后出现了一款超棒的布局方式,真正意义上的所见即所得,后面我们也会讲到 ...

  8. log4j输出日志到数据库中

    1.log4j配置 ###----------------- appender:DATABASE_LOG -----------------#指定输出日志的等级和日志输出范围log4j.logger. ...

  9. 【Spring源码分析】AOP源码解析(上篇)

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

  10. 33.Django ModelForm

    ModelForm 1.ModeForm简单验证 from django.db import models # Create your models here. class UserInfo(mode ...