设计模式(十四)--组合模式

目录

组合模式的关键概念

组合模式的优点

组合模式的缺点

例子:文件系统

步骤 1:定义Component接口

步骤 2:创建组合结构

输出结果

说明


组合模式(Composite Pattern)是一种结构型设计模式,它允许你组合对象形成树形结构来表示“部分-整体”的层次结构。组合模式让客户端能够一致地处理单个对象和组合对象,而无需关心它们的具体类型。这样,客户端代码可以透明地使用组合结构中的单个对象或整个组合。

组合模式的关键概念

  1. Component(组件)接口:定义了所有节点(叶子节点和分支节点)共有的操作。
  2. Leaf(叶子)类:实现Component接口,代表树形结构中的叶子节点。
  3. Composite(组合)类:也实现了Component接口,代表树形结构中的分支节点,它可以包含子Component对象。
  4. Client(客户端):通过Component接口来操作单个对象或组合对象。

组合模式的优点

  • 统一接口:客户端可以一致地对待单个对象和组合对象。
  • 递归结构:可以很容易地构建递归结构。
  • 灵活扩展:容易添加新的组件类型而不修改现有代码。

组合模式的缺点

  • 过度使用:如果不需要层次结构,那么使用组合模式可能会引入不必要的复杂性。
  • 复杂度增加:随着层次结构的加深,维护和理解代码可能会变得更加困难。

例子:文件系统

假设我们需要实现一个文件系统,其中包含文件夹和文件。文件夹可以包含其他文件夹和文件,而文件则不可再分割。

步骤 1:定义Component接口
 

c

深色版本

1#include <iostream>
2#include <vector>
3
4class Component {
5public:
6    virtual ~Component() {}
7    virtual void add(Component *component) = 0;
8    virtual void remove(Component *component) = 0;
9    virtual void display(int depth) = 0;
10};
11
12class Leaf : public Component {
13public:
14    Leaf(const std::string &name) : name(name) {}
15    void add(Component *component) override {
16        std::cout << "Cannot add to a leaf component." << std::endl;
17    }
18    void remove(Component *component) override {
19        std::cout << "Cannot remove from a leaf component." << std::endl;
20    }
21    void display(int depth) override {
22        printTabs(depth);
23        std::cout << "Leaf: " << name << std::endl;
24    }
25private:
26    void printTabs(int tabs) {
27        for (int i = 0; i < tabs; ++i) {
28            std::cout << "\t";
29        }
30    }
31    std::string name;
32};
33
34class Composite : public Component {
35public:
36    Composite(const std::string &name) : name(name) {}
37    void add(Component *component) override {
38        children.push_back(component);
39    }
40    void remove(Component *component) override {
41        children.erase(std::remove(children.begin(), children.end(), component), children.end());
42    }
43    void display(int depth) override {
44        printTabs(depth);
45        std::cout << "Composite: " << name << std::endl;
46        for (auto &child : children) {
47            child->display(depth + 1);
48        }
49    }
50private:
51    void printTabs(int tabs) {
52        for (int i = 0; i < tabs; ++i) {
53            std::cout << "\t";
54        }
55    }
56    std::string name;
57    std::vector<Component*> children;
58};
步骤 2:创建组合结构
 

c

深色版本

1int main() {
2    Composite *root = new Composite("Root Folder");
3
4    Composite *subFolder1 = new Composite("Sub Folder 1");
5    subFolder1->add(new Leaf("Document A"));
6    subFolder1->add(new Leaf("Document B"));
7
8    Composite *subFolder2 = new Composite("Sub Folder 2");
9    subFolder2->add(new Leaf("Document C"));
10
11    root->add(subFolder1);
12    root->add(subFolder2);
13    root->add(new Leaf("Document D"));
14
15    root->display(0);
16
17    delete root;
18    return 0;
19}

输出结果

 

plaintext

深色版本

1Composite: Root Folder
2	Composite: Sub Folder 1
3		Leaf: Document A
4		Leaf: Document B
5	Composite: Sub Folder 2
6		Leaf: Document C
7	Leaf: Document D

说明

在这个例子中:

  • Component 是抽象基类,定义了所有节点共有的方法。
  • Leaf 和 Composite 分别代表叶子节点和组合节点。
  • Composite 类可以包含多个 Component 对象,并提供了 add 和 remove 方法来管理子节点。
  • display 方法用于显示节点及其子节点的信息,客户端可以通过这个方法来遍历整个组合结构。

这个例子展示了如何使用组合模式来组织和操作文件系统中的文件夹和文件。通过这种模式,我们可以轻松地扩展系统,添加更多的功能,如搜索、排序等,而不改变现有的代码结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值