C++实现Structural - Composite模式

 

在面向对象的系统中,我们经常会遇到一类具有“容器”特征的对象,即它们在充当对象的同时,又是其他对象的容器。

举例:

在操作系统中,文件的概念很广泛,其中文件可以是普通文件,也可以是目录(在Unix中,设备也是文件),目录中可以存放文件。Composite设计模式就是将“客户代码与复杂的对象容器结构”解耦,让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象(文件)一样来处理复杂的对象容器(目录)。

 

“Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.” – GoF

 

调用Directory类对象的process函数,和调用PhysicalFile类对象的process一样简单。

 

从上面的UML类图中,可以看出Directory和File这两个类之间的关系:

1.       Directory “is a”File

2.       Directory “has a(more)” File

这是典型的递归结构。因此在处理递归问题时,如果必要,可以考虑采用Composite模式。后面要讲到的Decorator模式也是如此。

// Composite.h

#include <iostream>

#include <list>

using namespace std;

 

class File

{

public:

         virtual void process() = 0;

 

         // 虚函数:增加一个文件

         virtual void add(File* file)

         {

         }

 

         // 虚函数:删除一个文件

         virtual void remove(File* file)

         {

         }

 

public:

         virtual ~File()

         {

                   cout << "in the destructor of File..." << endl;

         }

};

 

// 叶子节点

class PhysicalFile : public File

{

public:

         void process()

         {

                   cout << "process() in PhysicalFile..." << endl;

         }

 

public:

         ~PhysicalFile()

         {

                   cout << "in the destructor of PhysicalFile..." << endl;

         }

};

 

// 容器节点:Composite节点

class Directory : public File

{

private:

         list<File*> file_list;

public:

         Directory()

         {

         }

 

         void process()

         {

                  cout << "process() in Directory..." << endl;

                  

                   if(!file_list.empty())

                   {

                            for(list<File*>::iterator it = file_list.begin(); it != file_list.end(); it++)

                            {

                                     File* f = *it;

                                     f->process();

                            }

                   }

         }

 

         void add(File* file)

         {

                   file_list.push_back(file);

         }

 

         void remove(File* file)

         {

                   file_list.remove(file);

         }

 

public:

         ~Directory()

         {

                   cout << "in the destructor of Directory..." << endl;

         }

};

 

// Composite.cpp

#include "Composite.h"

 

int main(int argc, char **argv)

{

         File *f1 = new Directory;

         File *f2 = new Directory;

         File *f3 = new PhysicalFile;

 

         f2->add(f3);

         f1->add(f2);

        

         File *f4 = new Directory;

         File *f5 = new Directory;

         File *f6 = new Directory;

         File *f7 = new PhysicalFile;

 

         f6->add(f7);

         f5->add(f6);

         f4->add(f5);

         f1->add(f4);

 

         f1->process();

 

         f1->remove(f4);

         cout << "+++++++++++++++++++++++" << endl;

         f1->process();

 

         // STL container中的元素是指针对象,那么必须手动删除。

         delete f1;

         delete f2;

         delete f3;

         delete f4;

         delete f5;

         delete f6;

         delete f7;

 

         return 0;

}

 

上述程序中,各对象之间的关系如下图:

其中f3和f7为PhysicalFile对象。f1包含了f2和f4,f2包含了f3,f4包含了f5,f5包含了f6,f6包含了f7。

 

运行结果如下:

process() in Directory...                                          // f1

process() in Directory...                                          // f2

process() in PhysicalFile...                                    // f3

process() in Directory...                                          // f4

process() in Directory...                                          // f5

process() in Directory...                                          // f6

process() in PhysicalFile...                                    // f7

+++++++++++++++++++++++                              // 删除f4后的输出(可以看到f4及其包含的对象全部被删除了)

process() in Directory...                                          // f1

process() in Directory...                                          // f2

process() in PhysicalFile...                                    // f3

in the destructor of Directory...

in the destructor of File...

in the destructor of Directory...

in the destructor of File...

in the destructor of PhysicalFile...

in the destructor of File...

in the destructor of Directory...

in the destructor of File...

in the destructor of Directory...

in the destructor of File...

in the destructor of Directory...

in the destructor of File...

in the destructor of PhysicalFile...

in the destructor of File...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值