组合模式(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;
}
关键点解析:
-
透明式设计:
- Component 基类定义了所有组件(包括叶子节点)的公共接口,包括
add/remove
等管理子组件的方法。 - 叶子节点 Leaf 继承自
Component
,但重写add/remove
时抛出异常(代码中省略异常以简化,实际可添加)。 - 组合节点 Composite 实现子组件管理逻辑,并递归调用子组件的
operation()
。
- Component 基类定义了所有组件(包括叶子节点)的公共接口,包括
-
内存管理:
- 使用
std::unique_ptr
管理子组件生命周期,确保组合对象析构时自动释放所有子组件。 - 避免手动
new/delete
,减少内存泄漏风险。
- 使用
-
递归结构:
- Composite 的
operation()
会遍历所有子组件并调用它们的操作,形成递归处理。
- Composite 的
输出结果:
Composite 执行操作,包含2个子组件:
Composite 执行操作,包含2个子组件:
Leaf[A] 执行操作
Leaf[B] 执行操作
Composite 执行操作,包含1个子组件:
Leaf[C] 执行操作
此实现展示了组合模式的核心思想:客户端无需区分叶子节点和组合节点 ,统一通过 Component
接口操作,简化了复杂树形结构的处理。