C++软件设计模式之组合模式与其他模式的协作举例

server/2024/11/30 14:51:28/

组合模式(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;
}

总结

  • 组合模式:处理对象的层次结构,使得客户端可以统一处理组合结构中的所有对象。
  • 装饰器模式:动态地扩展对象的功能,常用于扩展组合模式中的节点。
  • 享元模式:通过共享技术减少内存使用,常用于共享组合模式中的叶子节点。
  • 迭代器模式:提供顺序访问聚合对象的方法,常用于遍历组合模式的节点。
  • 访问者模式:在不修改已有类层次结构的情况下,定义新的操作,常用于对组合模式的节点执行不同操作。

这些模式可以在不同的场景下相互协作,从而提供更灵活和高效的解决方案。


http://www.ppmy.cn/server/146175.html

相关文章

Spark 内存管理机制

Spark 内存管理 堆内内存和堆外内存 作为一个 JVM 进程&#xff0c;Executor 的内存管理建立在 JVM(最小为六十四分之一&#xff0c;最大为四分之一)的内存管理之上&#xff0c;此外spark还引入了堆外内存&#xff08;不在JVM中的内存&#xff09;&#xff0c;在spark中是指不…

23种设计模式-工厂方法(Factory Method)设计模式

文章目录 一.什么是工厂方法设计模式&#xff1f;二. 工厂方法模式的特点三.工厂方法模式的结构四.工厂方法模式的优缺点五.工厂方法模式的 C 实现六.工厂方法模式的 Java 实现七.代码解析八.总结 类图&#xff1a; 工厂方法设计模式类图 一.什么是工厂方法设计模式&#xff1…

Matlab数字信号处理——音频信号处理与分析GUI

1.实现内容 实现功能有回响、变声、倒放、变速、音量调整、加噪、设计 FIR和 IR 滤波器实现去噪功能(高通低通带通带阻)&#xff0c;并且在时域波形图和频域波形展示变化。滤波器包括各种参数的选择、滤波器结构和类型的选择等。同时GUI上还包含打开、播放、保存、退出功能。 …

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一&#xff1a;是先有HTTP还是先有RPC&…

外卖点餐系统小程序

目录 开发前准备 项目展示项目分析项目初始化封装网络请求 任务1 商家首页 任务分析焦点图切换中间区域单击跳转到菜单列表底部商品展示 任务2 菜单列表 任务分析折扣信息区设计菜单列表布局请求数据实现菜单栏联动单品列表功能 任务3 购物车 任务分析设计底部购物车区域添加商…

ElasticSearch7.x入门教程之全文搜索(六)

文章目录 前言一、短语匹配&#xff1a;match_phrase query二、短语前缀匹配&#xff1a;~~match_phrase_prefix~~ query三、多字段查询&#xff1a;multi_match query四、Lucene中的简单查询五、存在查询&#xff1a;exists query六、前缀查询&#xff1a;~~prefix~~ query七、…

VSCode修改资源管理器文件目录树缩进(VSCode目录结构、目录缩进、文件目录外观)workbench.tree.indent

文章目录 方法点击左下角小齿轮点击设置点击工作台&#xff0c;点击外观&#xff0c;找到Tree: Indent设置目录树的缩进 方法 点击左下角小齿轮 点击设置 点击工作台&#xff0c;点击外观&#xff0c;找到Tree: Indent设置目录树的缩进 "workbench.tree.indent"默认…

【CSS in Depth 2 精译_064】10.3 CSS 中的容器查询相对单位 + 10.4 CSS 容器样式查询 + 10.5 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第十章 CSS 容器查询】 ✔️ 10.1 容器查询的一个简单示例 10.1.1 容器尺寸查询的用法 10.2 深入理解容器 10.2.1 容器的类型10.2.2 容器的名称10.2.3 容器与模块化 CSS 10.3 与容器相关的单位 ✔…