设计模式 --> (8)组合模式

组合模式

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

适用性

  常用于组织结构,产品结构之类的整体和部分的结构。例如图形由很多直线构成,直线由点构成,这就是整体和部分的关系。如果采用组合模式,只需要使用一个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 = 0;i < depth; i++)
            cout<<"-";
        cout<<m_name<<endl;
        list<Company *>::iterator iter=m_listCompany.begin();
        for(; iter != m_listCompany.end(); iter++) //显示下层结点
            (*iter)->Show(depth + 2);
    }
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 = 0; 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 = 0; 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(0);  

    delete leaf1; delete leaf2;
    delete leaf3; delete leaf4;
    delete leaf5; delete leaf6;
    delete mid1; delete mid2;
    delete root;
    return 0;
} 

结果:

总公司
--财务部
--人力资源部
--分公司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() = 0;
};

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 0;
}

结果:

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

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

时间: 2024-07-30 20:31:54

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

设计模式之组合模式

当需求中是体现部分与整体层次的结构时,以及你希望忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑使用组合模式了.例如:我们单个复制一个文件和多个复制文件,对我们而言,并不在乎一个文件的复制与多个文件复制的区别,也就是我们的操作是一样的. 下面的代码是建立一个公司的组织结构,其中各个部分,不管是分公司还是部门,都拥有一套相同的功能操作. 代码如下: using System; using System.Collections.Generic; using System.L

设计模式之组合模式(Composite)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

设计模式之组合模式(Composite)

1.定义 组合模式(Composite Pattern)也叫合成模式,将对象组合成树形结构以表示"整体-部分"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.通用类图 Component抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性. Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位. Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构. 3.通用源代码 package Compo

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

今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合模式的类图一本结构 想了很久,结合源代码,才搞明白,其实这个组合,意思就是说,如果我们要做这种树状结果,比如公司想让我们吧所有部门人员的 姓名,职位,薪水遍历出来,这个时候怎么办呢?那我们看树状机构图,有叶子结点和枝干结点,2种,但是2种有共性,那就是每个结点都有姓名,职位,薪水.所有叶子结点和枝干

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

一,C#设计模式:组合模式(Composite Pattern) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _9.组合模式 { //组合模式主要用来处理一类具有"容器特征"的对象--即它们在充当对象的同时,又可以作为容器包含其他多个对象. //组合模式,将对象组合成树形结构以表示

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

一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象在功能上区别,导致在操作过程中必须区分简单对象和复合对象,这样就会导致客户调用带来不必要的麻烦,然而作为客户,它们希望能够始终一致地对待简单对象和复合对象.然而组合模式就是解决这样的问题.下面让我们看看组合模式是怎样解决这个问题的. 二.组合模式的详细介绍 2.1 组合模式的定义 组合模式

每天一个设计模式之组合模式

作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 原文地址是:<每天一个设计模式之组合模式> 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端).知识整理(每周零碎),欢迎长期关注! 如果您也想进行知识整理 + 搭建功能完善/设计简约/快速启动的个人博客,请直接戳the

图解Java设计模式之组合模式

图解Java设计模式之组合模式 看一个学校院系展示需求 传统方案解决学院院系展示(类图) 传统方案解决学校院系展示存在的问题分析 组合模式基本介绍 组合模式的原理类图 组合模式解决学校院系展示的应用实例 组合模式在JDK集合的源码分析 组合模式的注意事项和细节 看一个学校院系展示需求 编写程序展示一个学校院系结构 :需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系.如图 : 传统方案解决学院院系展示(类图) 传统方案解决学校院系展示存在的问题分析 1)将学院看

10.设计模式_组合模式

转载自   http://www.cnblogs.com/zhili/p/CompositePattern.html 一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象在功能上区别,导致在操作过程中必须区分简单对象和复合对象,这样就会导致客户调用带来不必要的麻烦,然而作为客户,它们希望能够始终一致地对待简单对象和复合对象.然而组合模式就是

【设计模式】组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 这种模式创建了一个包含自己对象组的类.该类提供了修改相同对象组的方式. 我们通过下面的实例来演示组合模式的用法.实例演示了一个组织中员工的层次结构. 介绍 意图:将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一