概念
组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表现“整体-部分”的层次关系。组合能让客户以一致的方式处理个别对象以及对象组合。
组合模式在以下情况下特别有用:
- 当你希望客户端代码以相同的方式处理简单对象和复杂对象时。
- 当你希望以一种组织结构的方式来表示对象的部分-整体层次结构。
在C++中实现组合模式,你可以定义一个抽象的组件类,它可以包含某些被子组件共享的通用接口。然后,你可以定义具体的组件类,它们可以是叶子节点,也可以是容器节点,容器节点可以包含其他组件。
以下是一个简单的例子:
这个例子中,Component
是一个抽象类,它定义了所有组件共有的接口。Leaf
类实现了 Component
的接口,并且表示叶子节点,它不包含任何子组件。Composite
类同样实现了 Component
的接口,并且可以包含子组件。在 main
函数中,我们创建了一个由叶子节点和容器节点组成的简单组件结构,并展示了这些组件。最后,我们删除了所有创建的对象以释放资源。
#include <iostream>
#include <vector>
// 抽象组件类
class Component {
public:
virtual ~Component() {}
virtual void Add(Component*) {}
virtual void Remove(Component*) {}
virtual void Display(int) const = 0;
};
// 叶子组件类
class Leaf : public Component {
public:
void Display(int indent) const override {
std::cout << std::string(indent, '-') << " Leaf" << std::endl;
}
};
// 容器组件类
class Composite : public Component {
public:
void Add(Component* component) override {
children.push_back(component);
}
void Remove(Component* component) override {
children.erase(std::remove(children.begin(), children.end(), component), children.end());
}
void Display(int indent) const override {
std::cout << std::string(indent, '-') << " Composite" << std::endl;
for (const auto& child : children) {
child->Display(indent + 2);
}
}
private:
std::vector<Component*> children;
};
int main() {
// 创建组件
Composite* root = new Composite();
root->Add(new Leaf());
Composite* branch = new Composite();
branch->Add(new Leaf());
branch->Add(new Leaf());
root->Add(branch);
root->Add(new Leaf());
// 显示组件
root->Display(2);
// 清理资源
delete root;
delete branch;
return 0;
}
使用图形和图形集合作为示例:
#include <iostream>
#include <vector>
// 组件基类
class Graphic {
public:
virtual void draw() = 0;
};
// 叶子节点类: 线条
class Line : public Graphic {
public:
void draw() override {
std::cout << "Drawing Line" << std::endl;
}
};
// 叶子节点类: 圆形
class Circle : public Graphic {
public:
void draw() override {
std::cout << "Drawing Circle" << std::endl;
}
};
// 容器节点类: 图形集合
class Picture : public Graphic {
private:
std::vector<Graphic*> graphics;
public:
void add(Graphic* graphic) {
graphics.push_back(graphic);
}
void draw() override {
std::cout << "Drawing Picture:" << std::endl;
for (Graphic* graphic : graphics) {
graphic->draw();
}
}
};
int main() {
Line* line = new Line();
Circle* circle = new Circle();
Picture* picture = new Picture();
picture->add(line);
picture->add(circle);
picture->draw();
delete line;
delete circle;
delete picture;
return 0;
}
在这个示例中,我们创建了Graphic
基类,并从中派生了Line
和Circle
作为叶子节点,以及Picture
作为容器节点。然后我们演示了如何将叶子节点和容器节点组合成一个树形结构,并以统一的方式进行处理和绘制。