组合模式(composite)-设计模式(八)

一、作用:
将对象组合成树形结构以表示”部分-整体”的层次结构。 Composite 使得用户对单个对象和组合对象的使用具有一致性。
有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
  组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
二、结构
这里写图片描述 
典型的Composite结构:
这里写图片描述
抽象基类:
l)Component:为组合中的对象声明接口, 声明了类共有接口的缺省行为(如这里的
Add,Remove,GetChild 函数),声明一个接口函数可以访问 Component 的子组
件.
接口函数:
1)Component::Operatation:定义了各个组件共有的行为接口, 由各个组件具体实现.
2)Component::Add 添加一个子组件
3)Component::Remove::删除一个子组件.
4)Component::GetChild:获得子组件的指针
解析:
Component 模式是为解决组件之间的递归组合提供了解决的办法,它主要分为两个派生类,其中的 Leaf 是叶子结点,也就是不含有子组件的结点, 而 Composite 是含有子组件的类.举一个例子来说明这个模式,在 UI 的设计中,最基本的控件是诸如Button,Edit 这样的控件,相当于是这里的 Leaf 组件,而比较复杂的控件比如 List 则可也看做是由这些基本的组件组合起来的控件,相当于这里的 Composite,它们之间有一些行为含义是相同的,比如在控件上作一个点击,移动操作等等的,这些都可以定义为抽象基类中的接口虚函数,由各个派生类去实现之,这些都会有的行为就是这里的Operation 函数,而添加,删除等进行组件组合的操作只有非叶子结点才可能有,所以虚拟基类中只是提供接口而且默认的实现是什么都不做.
接下来看一个实现:这个实现出自:
http://www.cnblogs.com/djcsch2001/archive/2011/05/17/2049239.html

#include <iostream>
#include <list>
#include <string>

 using namespace std;

 class AbstractFile {
protected:
    string name;   /*文件或目录名*/
public:
    void printName() {cout<<name<<endl;}    /*打印文件或目录名称*/
    virtual void addChild(AbstractFile *file)=0;  /*给一个目录增加子目录或文件*/
    virtual void removeChild(AbstractFile *file)=0;  /*删除一个目录的子目录或文件*/
    virtual list<AbstractFile *> *getChildren()=0;   /*保存一个目录的子目录或文件*/
};

class File:public AbstractFile{
public:
    File(string name) {this->name=name;}
    void addChild(AbstractFile *file) {return;}
    void removeChild(AbstractFile *file) {return;}
    list<AbstractFile *> *getChildren() {return NULL;}
};

class Folder:public AbstractFile {
private:
    list<AbstractFile *> childList;   /*存储子目录或文件*/
public:
    Folder(string name) {this->name=name;}
    void addChild(AbstractFile *file) {childList.push_back(file);}
    void removeChild(AbstractFile *file) {childList.remove(file);}
    list<AbstractFile *> *getChildren() {return &childList;}
};

int main() {
    AbstractFile *rootFolder=new Folder("c:\\");
    AbstractFile *compositeFolder=new Folder("composite");
    AbstractFile *WindowsFolder=new Folder("Windows");
    AbstractFile *file=new File("TestComposite.C++");
    rootFolder->addChild(compositeFolder);
    rootFolder->addChild(WindowsFolder);
    compositeFolder->addChild(file);
    rootFolder->printName();
    compositeFolder->printName();
    WindowsFolder->printName();
    file->printName();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值