设计模式【9】——组合模式(Composite 模式)


前言

Composite(组合模式)是一种管理树形结构的抽象方式。其是将对象组合成树形结构,从而构成表示 “部分 - 整体” 的层次结构。这种层次关系在日产生活中十分常见。如在公司组织关系中,可能分为部门与人,其中人属于部门,有的人有下属,有的人没有下属。假如将部门、人等都抽象成为一个节点(不用关心当前节点是部门还是人,两者有公共的基类),这样的话公司的组织架构就十分清晰,而且某个部门下有多少人、财务数据等这些数据也容易统计。除了公司外,在操作系统中也普遍应用,其中的文件夹与文件就是典型的树状结构,为了保证扩展性与可维护性,在设计时可以将文件夹与文件抽象为文件,这样每个节点都拥有相同的方法添加、删除、查找子元素,无需要关心当前节点的具体类型。下面我们予以详细的介绍


一、组合模式(Composite 模式)

Composite 和 Leaf需要实现部分同样的接口,其中Leaf(文件或者人)类需要实现Operation的功能,其他的不需要实现,而Composite(文件夹或者部门)类除了要实现Operation功能外,还需实现添加、删除、查询等功能。因此Composite 和 Leaf有着一个共同的父类——Component。这样,两者都可以通过Component*来统一进行调用了。UML图如下:
Composite 模式示意图

二、具体源码

1.Composite.h

代码如下(示例):

#pragma once

#ifndef _COMPOSITE_H_ 
#define _COMPOSITE_H_ 

#include <iostream>
#include <algorithm>
#include <vector>

class Component
{
public:

  Component();
  virtual ~Component();

public:

  //Leaf和Composite统一的接口
  virtual void Operation() = 0;
  virtual void Add(const Component&);
  virtual void Remove(const Component&);
  virtual Component* GetChild(int);

protected:
private:
};

class Composite :public Component
{
public:

  Composite();
  ~Composite();

public:

  void Operation();
  void Add(Component* com);
  void Remove(Component* com);
  Component* GetChild(int index);
protected:
private:
  //存储树结构下面相关数据,例如,一个文件夹下面肯定还有文件夹以及文件
  std::vector<Component*> comVec;
};

class Leaf :public Component
{
public:

  Leaf();
  ~Leaf();
  //Leaf就相当于树结构的最后一层,无需添加、删除、查询等功能
  void Operation();
protected:
private:
};

#endif //~_COMPOSITE_H_

2.Composite.cpp

代码如下(示例):

#include "Composite.h" 

Component::Component()
{
}

Component::~Component()
{
}

void Component::Add(const Component& com)
{
}

Component* Component::GetChild(int index)
{
  return 0;
}

void Component::Remove(const Component& com)
{
}

Composite::Composite()
{
  //当然,内部成员comVec也可以在构造函数内进行初始化,具体的就不列出了 
}
Composite::~Composite()
{
}
void Composite::Operation()
{
  std::vector<Component*>::iterator comIter = comVec.begin();
  for (; comIter != comVec.end(); comIter++)
  {
    (*comIter)->Operation();
  }
}

void Composite::Add(Component* com)
{
  comVec.push_back(com);
}

void Composite::Remove(Component* com)
{
  std::remove(comVec.begin(),comVec.end(),com);
}

Component* Composite::GetChild(int index)
{
  return comVec[index];
}

Leaf::Leaf()
{
}

Leaf::~Leaf()
{

}

void Leaf::Operation()
{
  std::cout << "Leaf operation....." << std::endl;
}

3.main.cpp

代码如下(示例):

#include "Composite.h" 

int main(int argc, char* argv[])
{
  Leaf* l = new Leaf();
  l->Operation();

  Composite* com = new Composite();
  com->Add(l);
  com->Operation();

  Component* ll = com->GetChild(0);
  ll->Operation();

  return 0;
}

三、运行结果

Composite 模式运行结果如下:
Composite 模式运行结果


总结

Composite 模式在实现中有一个问题就是要提供对于子节点(Leaf)的管理策略,这里使用的是 STL 中的 vector,可以提供其他的实现方式,如数组、链表、Hash 表等。
Composite 模式可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了代码开发;而且更容易在组合体内加入新的对象,满足“开闭原则”;但是,其层次结构较复杂,需要花更多时间理清类之间的层次关系,而且不容易用继承的方法来增加构件的新功能。
Composite 模式通过和 Decorator 模式有着类似的结构图,但是 Composite 模式旨在构造类,而 Decorator 模式重在不生成子类即可给对象添加职责。Decorator 模式重在修饰,而Composite 模式重在表示


本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希望早日退休的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值