C++软件设计模式之组合模式与其他模式的协作举例
组合模式(Composite Pattern)、装饰器模式(Decorator Pattern)、享元模式(Flyweight Pattern)、迭代器模式(Iterator Pattern)和访问者模式(Visitor Pattern)是五种常见的设计模式,它们各自解决不同的问题,但在某些场景下可以相互协作。以下是它们之间的关联以及如何在C++中结合使用这些模式的示例。
组合模式与装饰器模式的关联
组合模式处理对象的层次结构,而装饰器模式处理对象功能的动态扩展。在某些情况下,可以使用装饰器模式来装饰组合模式中的节点,从而在不修改组合结构的情况下扩展其功能。
示例:使用装饰器模式扩展组合模式中的节点
#include <iostream>
#include <vector>
// 组合模式部分
class Component {
public:
virtual void operation() = 0;
virtual ~Component() {}
};
class Leaf : public Component {
public:
void operation() override {
std::cout << "Leaf operation" << std::endl;
}
};
class Composite : public Component {
public:
void add(Component* component) {
components.push_back(component);
}
void operation() override {
std::cout << "Composite operation" << std::endl;
for (auto& component : components) {
component->operation();
}
}
private:
std::vector<Component*> components;
};
// 装饰器模式部分
class Decorator : public Component {
protected:
Component* component;
public:
Decorator(Component* component) : component(component) {}
void operation() override {
component->operation();
}
};
class BorderDecorator : public Decorator {
public:
BorderDecorator(Component* component) : Decorator(component) {}
void operation() override {
Decorator::operation();
std::cout << "Adding border" << std::endl;
}
};
int main() {
Composite* root = new Composite();
root->add(new Leaf());
root->add(new Leaf());
Composite* subComposite = new Composite();
subComposite->add(new Leaf());
root->add(subComposite);
// 使用装饰器模式扩展组合模式中的节点
Component* decoratedRoot = new BorderDecorator(root);
decoratedRoot->operation();
delete decoratedRoot;
return 0;
}
组合模式与享元模式的关联
享元模式通过共享技术来有效地支持大量细粒度的对象。在组合模式中,可以使用享元模式来共享叶子节点或部分组合节点,从而减少内存使用。
示例:使用享元模式共享组合模式中的叶子节点
#include <iostream>
#include <vector>
#include <unordered_map>
// 享元模式部分
class Flyweight {
public:
virtual void operation() = 0;
virtual ~Flyweight() {}
};
class ConcreteFlyweight : public Flyweight {
public:
void operation() override {
std::cout << "ConcreteFlyweight operation" << std::endl;
}
};
class FlyweightFactory {
public:
Flyweight* getFlyweight(const std::string& key) {
if (flyweights.find(key) == flyweights.end()) {
flyweights[key] = new ConcreteFlyweight();
}
return flyweights[key];
}
private:
std::unordered_map<std::string, Flyweight*> flyweights;
};
// 组合模式部分
class Component {
public:
virtual void operation() = 0;
virtual ~Component() {}
};
class Leaf : public Component {
public:
Leaf(Flyweight* flyweight) : flyweight(flyweight) {}
void operation() override {
flyweight->operation();
}
private:
Flyweight* flyweight;
};
class Composite : public Component {
public:
void add(Component* component) {
components.push_back(component);
}
void operation() override {
std::cout << "Composite operation" << std::endl;
for (auto& component : components) {
component->operation();
}
}
private:
std::vector<Component*> components;
};
int main() {
FlyweightFactory factory;
Composite* root = new Composite();
root->add(new Leaf(factory.getFlyweight("leaf1")));
root->add(new Leaf(factory.getFlyweight("leaf1"))); // 共享相同的享元对象
root->add(new Leaf(factory.getFlyweight("leaf2")));
root->operation();
delete root;
return 0;
}
组合模式与迭代器模式的关联
迭代器模式提供了一种顺序访问聚合对象中各个元素的方法,而不暴露其内部表示。在组合模式中,可以使用迭代器模式来遍历组合结构的节点。
示例:使用迭代器模式遍历组合模式中的节点
#include <iostream>
#include <vector>
// 组合模式部分
class Component {
public:
virtual void operation() = 0;
virtual ~Component() {}
};
class Leaf : public Component {
public:
void operation() override {
std::cout << "Leaf operation" << std::endl;
}
};
class Composite : public Component {
public:
void add(Component* component) {
components.push_back(component);
}
void operation() override {
std::cout << "Composite operation" << std::endl;
for (auto& component : components) {
component->operation();
}
}
// 迭代器模式实现
class Iterator {
public:
Iterator(const std::vector<Component*>& components) : components(components), index(0) {}
bool hasNext() {
return index < components.size();
}
Component* next() {
return components[index++];
}
private:
std::vector<Component*> components;
size_t index;
};
Iterator* createIterator() {
return new Iterator(components);
}
private:
std::vector<Component*> components;
};
int main() {
Composite* root = new Composite();
root->add(new Leaf());
root->add(new Leaf());
Composite* subComposite = new Composite();
subComposite->add(new Leaf());
root->add(subComposite);
// 使用迭代器模式遍历组合模式的节点
Composite::Iterator* iterator = root->createIterator();
while (iterator->hasNext()) {
iterator->next()->operation();
}
delete root;
delete iterator;
return 0;
}
组合模式与访问者模式的关联
访问者模式允许你在不修改已有类层次结构的情况下,定义新的操作。在组合模式中,可以使用访问者模式来对组合结构的节点执行不同的操作。
示例:使用访问者模式对组合模式中的节点执行不同操作
#include <iostream>
#include <vector>
// 组合模式部分
class Component {
public:
virtual void accept(class Visitor*) = 0;
virtual ~Component() {}
};
class Leaf : public Component {
public:
void accept(Visitor* visitor) override;
};
class Composite : public Component {
public:
void add(Component* component) {
components.push_back(component);
}
void accept(Visitor* visitor) override;
private:
std::vector<Component*> components;
};
// 访问者模式部分
class Visitor {
public:
virtual void visitLeaf(Leaf* leaf) = 0;
virtual void visitComposite(Composite* composite) = 0;
};
class PrintVisitor : public Visitor {
public:
void visitLeaf(Leaf* leaf) override {
std::cout << "Visiting Leaf" << std::endl;
}
void visitComposite(Composite* composite) override {
std::cout << "Visiting Composite" << std::endl;
for (auto& component : composite->components) {
component->accept(this);
}
}
};
void Leaf::accept(Visitor* visitor) {
visitor->visitLeaf(this);
}
void Composite::accept(Visitor* visitor) {
visitor->visitComposite(this);
}
int main() {
Composite* root = new Composite();
root->add(new Leaf());
root->add(new Leaf());
Composite* subComposite = new Composite();
subComposite->add(new Leaf());
root->add(subComposite);
// 使用访问者模式对组合模式的节点执行操作
PrintVisitor visitor;
root->accept(&visitor);
delete root;
return 0;
}
总结
- 组合模式:处理对象的层次结构,使得客户端可以统一处理组合结构中的所有对象。
- 装饰器模式:动态地扩展对象的功能,常用于扩展组合模式中的节点。
- 享元模式:通过共享技术减少内存使用,常用于共享组合模式中的叶子节点。
- 迭代器模式:提供顺序访问聚合对象的方法,常用于遍历组合模式的节点。
- 访问者模式:在不修改已有类层次结构的情况下,定义新的操作,常用于对组合模式的节点执行不同操作。
这些模式可以在不同的场景下相互协作,从而提供更灵活和高效的解决方案。