组合模式

组合模式相较于我们对象设计中的组合关系是两个不同的概念:

  1. 组合模式(Composite Pattern)是一种设计模式,它将对象组合成树形结构来表示部分-整体层次结构。组合模式允许客户端统一地使用个别对象和组合对象。
  2. 组合关系(Composition)是对象之间的一种强关联关系,表示部分和整体的关系,部分对象无法脱离整体对象独立存在。这种部分与整体的关系不同于关联关系和聚合关系。

主要区别:

  • 组合模式是一种设计模式,重点在于统一处理个别对象和组合对象。
  • 组合关系是描述类之间关系的一种关联方式,强调部分与整体之间不可分的强依赖性。
  • 组合模式使用了组合关系,即组合对象与部分对象之间形成了强依赖,部分对象不能脱离组合对象独立存在。
  • 但是实现组合模式不一定需要使用组合关系,也可以通过关联关系来实现。

总之,组合模式是一种设计模式,利用组合关系或者关联关系来统一对待部分和整体对象。组合关系是描述部分和整体间强依赖关联的一种方式。

介绍

组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次关系。

组合模式的定义:将对象组合成树形结构以表示部分-整体层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式的主要角色:

  • Component:组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。
  • Leaf:叶子构件,叶子对象没有子对象,定义叶子对象的行为。
  • Composite:容器构件,存储子部件,在Component接口中实现子部件管理的相关操作,如添加和删除等。

组合模式的适用场景:表示对象的部分-整体层次结构(树形结构)。

定义

我们要构建一个文件系统,它包含文件和文件夹。文件和文件夹有一些共同的操作,比如获取名称、获取大小等。但是它们也有一些不同的操作,例如文件可以读取内容,文件夹可以添加子文件和子文件夹。

基类 含有共同属性

class Entry {
  string name;
  int size;

 public:
  Entry(string name) { this->name = name; }
  void setSize(int size) { this->size = size; }
  string getName() { return name; }
  int getSize() { return size; }
  virtual void read(std::string space = " ") = 0;
};

文件 包含内容

class File : public Entry {
  string content;

 public:
  File(string name, string content) : Entry(name) {
    this->content = content;
    setSize(content.size());
  }
  void read(std::string space = " ") override {
    std::cout << space;
    std::cout << "File : " << getName() << " size [" << getSize()
              << "] content[" << content << "]" << std::endl;
  }
};

文件夹 可包含多个文件以及文件夹

class Folder : public Entry {
  vector<std::shared_ptr<Entry>> children;

 public:
  Folder(string name) : Entry(name) { setSize(0); }
  void addEntry(std::shared_ptr<Entry> entry) {
    children.push_back(entry);
    setSize(getSize() + entry->getSize());
  }
  void read(std::string space = " ") override {
    std::cout << space;
    std::cout << "Folder : " << getName() << " size[" << getSize() << "]"
              << std::endl;
    for (auto child : children) {
      child->read(space + " ");
    }
  }
};

调用

std::shared_ptr<Folder> root = std::make_shared<Folder>("root");
std::shared_ptr<Folder> second = std::make_shared<Folder>("sec");
second->addEntry(std::make_shared<File>("sex.md", "this is a girl"));
root->addEntry(std::make_shared<File>("readme.md", "for test"));
root->addEntry(second);
root->addEntry(std::make_shared<File>("readme2.md", "for test2"));
root->read();

效果

./bin/design/composite
 Folder : root size[31]
  File : readme.md size [8] content[for test]
  Folder : sec size[14]
   File : sex.md size [14] content[this is a girl]
  File : readme2.md size [9] content[for test2]

回顾

组合模式的设计思路,与其说是一种设计模式,倒不如说是对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。

组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值