C++ 设计模式-组合模式

组合模式(Composite Pattern)允许将对象组合成树形结构,使得客户端以统一的方式处理单个对象和组合对象。以下是一个经典的 C++ 实现示例,包含透明式设计(基类定义统一接口)和内存管理:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <memory>

// 抽象组件类
class Component {
public:
    virtual ~Component() = default;
    virtual void operation() const = 0;
    
    // 管理子组件的透明接口(Leaf需处理不支持的操作)
    virtual void add(std::unique_ptr<Component> component) {
        throw std::runtime_error("Unsupported operation: add");
    }
    virtual void remove(Component* component) {
        throw std::runtime_error("Unsupported operation: remove");
    }
    virtual const Component* getChild(int index) const {
        throw std::runtime_error("Unsupported operation: getChild");
    }
};

// 叶子节点类
class Leaf : public Component {
public:
    explicit Leaf(std::string name) : name_(std::move(name)) {}
    
    void operation() const override {
        std::cout << "Leaf[" << name_ << "] 执行操作" << std::endl;
    }
    
private:
    std::string name_;
};

// 组合节点类
class Composite : public Component {
public:
    void operation() const override {
        std::cout << "Composite 执行操作,包含" << children_.size() << "个子组件:" << std::endl;
        for (const auto& child : children_) {
            child->operation(); // 递归调用子组件的操作
        }
    }
    
    void add(std::unique_ptr<Component> component) override {
        children_.push_back(std::move(component));
    }
    
    void remove(Component* component) override {
        auto it = std::find_if(children_.begin(), children_.end(),
            [component](const std::unique_ptr<Component>& c) {
                return c.get() == component;
            });
        if (it != children_.end()) {
            children_.erase(it);
        }
    }
    
    const Component* getChild(int index) const override {
        if (index >= 0 && index < children_.size()) {
            return children_[index].get();
        }
        return nullptr;
    }

private:
    std::vector<std::unique_ptr<Component>> children_; // 使用智能指针管理生命周期
};

// 客户端代码
int main() {
    // 创建组合结构:root -> [branch1, branch2]
    // branch1 -> [leaf1, leaf2]
    // branch2 -> [leaf3]
    auto root = std::make_unique<Composite>();
    
    auto branch1 = std::make_unique<Composite>();
    branch1->add(std::make_unique<Leaf>("A"));
    branch1->add(std::make_unique<Leaf>("B"));
    
    auto branch2 = std::make_unique<Composite>();
    branch2->add(std::make_unique<Leaf>("C"));
    
    root->add(std::move(branch1));
    root->add(std::move(branch2));
    
    // 统一调用操作
    root->operation();
    
    return 0;
}

关键点解析:

  1. 透明式设计

    • Component 基类定义了所有组件(包括叶子节点)的公共接口,包括 add/remove 等管理子组件的方法。
    • 叶子节点 Leaf 继承自 Component,但重写 add/remove 时抛出异常(代码中省略异常以简化,实际可添加)。
    • 组合节点 Composite 实现子组件管理逻辑,并递归调用子组件的 operation()
  2. 内存管理

    • 使用 std::unique_ptr 管理子组件生命周期,确保组合对象析构时自动释放所有子组件。
    • 避免手动 new/delete,减少内存泄漏风险。
  3. 递归结构

    • Compositeoperation() 会遍历所有子组件并调用它们的操作,形成递归处理。

输出结果:

复制代码
Composite 执行操作,包含2个子组件:
Composite 执行操作,包含2个子组件:
Leaf[A] 执行操作
Leaf[B] 执行操作
Composite 执行操作,包含1个子组件:
Leaf[C] 执行操作

此实现展示了组合模式的核心思想:客户端无需区分叶子节点和组合节点 ,统一通过 Component 接口操作,简化了复杂树形结构的处理。

相关推荐
草原上唱山歌18 小时前
推荐学习的C++书籍
开发语言·c++·学习
sxlishaobin19 小时前
设计模式之原型模式
设计模式·原型模式
2501_9418752819 小时前
在东京复杂分布式系统中构建统一可观测性平台的工程设计实践与演进经验总结
c++·算法·github
Jacen.L19 小时前
SIGABRT (6) 中止信号详解
c++
王老师青少年编程19 小时前
信奥赛C++提高组csp-s之并查集(案例实践)2
数据结构·c++·并查集·csp·信奥赛·csp-s·提高组
范纹杉想快点毕业20 小时前
嵌入式通信核心架构:从状态机、环形队列到多协议融合
linux·运维·c语言·算法·设计模式
__万波__20 小时前
二十三种设计模式(二十)--解释器模式
java·设计模式·解释器模式
攀登的牵牛花20 小时前
前端向架构突围系列 - 架构方法(一):概述 4+1 视图模型
前端·设计模式·架构
满天星830357720 小时前
【C++】特殊类设计
c++·windows
雲墨款哥20 小时前
从一行好奇的代码说起:React的 useEffect 到底是不是生命周期?
前端·react.js·设计模式