C++实现设计模式---装饰器模式 (Decorator)

server/2025/1/20 2:10:46/

装饰器模式 (Decorator)

装饰器模式 是一种结构型设计模式,它允许动态地将责任附加到对象上,既可以在运行时给一个对象添加功能,又不会影响其他对象的功能。


意图

  • 动态地扩展对象的功能。
  • 避免创建过多的子类,通过装饰器来“包装”对象,添加新功能。
  • 保持类的单一职责和开放封闭原则。

使用场景

  1. 系统需要动态地添加功能给对象
    • 如UI框架中的组件装饰,能动态增加功能(如窗口的滚动条、边框等)。
  2. 不希望通过继承来扩展对象功能
    • 继承可能会导致类的数量激增,装饰器模式能够解决这个问题。
  3. 功能扩展需要灵活控制
    • 可以在不同的对象上应用不同的装饰,不会互相影响。

参与者角色

  1. 组件接口 (Component)
    • 定义基本对象行为的接口,所有的装饰器和具体对象都需要实现此接口。
  2. 具体组件 (ConcreteComponent)
    • 具体实现基本行为的对象。
  3. 装饰器 (Decorator)
    • 持有组件的引用,并实现组件接口,增强功能。
  4. 具体装饰器 (ConcreteDecorator)
    • 通过调用被装饰对象的方法来添加额外功能。

示例代码

以下代码展示了如何使用装饰器模式扩展一个简单的咖啡类。

#include <iostream>
#include <string>// 组件接口
class Beverage {
public:virtual ~Beverage() = default;virtual std::string getDescription() const = 0;virtual double cost() const = 0;
};// 具体组件:咖啡
class Coffee : public Beverage {
public:std::string getDescription() const override {return "Coffee";}double cost() const override {return 5.0;}
};// 装饰器基类
class BeverageDecorator : public Beverage {
protected:Beverage* beverage;public:BeverageDecorator(Beverage* b) : beverage(b) {}virtual ~BeverageDecorator() = default;
};// 具体装饰器:加入牛奶
class MilkDecorator : public BeverageDecorator {
public:MilkDecorator(Beverage* b) : BeverageDecorator(b) {}std::string getDescription() const override {return beverage->getDescription() + ", Milk";}double cost() const override {return beverage->cost() + 1.0;}
};// 具体装饰器:加入糖
class SugarDecorator : public BeverageDecorator {
public:SugarDecorator(Beverage* b) : BeverageDecorator(b) {}std::string getDescription() const override {return beverage->getDescription() + ", Sugar";}double cost() const override {return beverage->cost() + 0.5;}
};// 客户端代码
int main() {Beverage* coffee = new Coffee();  // 创建基本的咖啡std::cout << coffee->getDescription() << " Cost: $" << coffee->cost() << std::endl;// 加入牛奶的装饰coffee = new MilkDecorator(coffee);std::cout << coffee->getDescription() << " Cost: $" << coffee->cost() << std::endl;// 再加入糖的装饰coffee = new SugarDecorator(coffee);std::cout << coffee->getDescription() << " Cost: $" << coffee->cost() << std::endl;// 清理内存delete coffee;return 0;
}

代码解析

1. 组件接口

  • Beverage 类是所有具体组件和装饰器的公共接口,定义了所有具体对象的行为:
class Beverage {
public:virtual ~Beverage() = default;virtual std::string getDescription() const = 0;virtual double cost() const = 0;
};

2. 具体组件

  • Coffee 是具体的组件,提供了描述和计算费用的功能:
class Coffee : public Beverage {
public:std::string getDescription() const override {return "Coffee";}double cost() const override {return 5.0;}
};

3. 装饰器基类

  • BeverageDecorator 继承了 Beverage,并持有一个 Beverage 对象,能够动态地扩展其功能:
class BeverageDecorator : public Beverage {
protected:Beverage* beverage;public:BeverageDecorator(Beverage* b) : beverage(b) {}virtual ~BeverageDecorator() = default;
};

4. 具体装饰器

  • MilkDecoratorSugarDecorator 是具体的装饰器类,分别增加了 MilkSugar 的功能:
class MilkDecorator : public BeverageDecorator {
public:MilkDecorator(Beverage* b) : BeverageDecorator(b) {}std::string getDescription() const override {return beverage->getDescription() + ", Milk";}double cost() const override {return beverage->cost() + 1.0;}
};
class SugarDecorator : public BeverageDecorator {
public:SugarDecorator(Beverage* b) : BeverageDecorator(b) {}std::string getDescription() const override {return beverage->getDescription() + ", Sugar";}double cost() const override {return beverage->cost() + 0.5;}
};

5. 客户端

  • 客户端可以按需为原始对象添加装饰,每次调用 getDescriptioncost 时,都能看到新添加的功能:
int main() {Beverage* coffee = new Coffee();  std::cout << coffee->getDescription() << " Cost: $" << coffee->cost() << std::endl;coffee = new MilkDecorator(coffee);std::cout << coffee->getDescription() << " Cost: $" << coffee->cost() << std::endl;coffee = new SugarDecorator(coffee);std::cout << coffee->getDescription() << " Cost: $" << coffee->cost() << std::endl;delete coffee;return 0;
}

优缺点

优点

  1. 动态扩展功能
    • 可以在运行时为对象添加新功能。
  2. 避免子类数量暴增
    • 通过装饰器而不是继承来扩展功能,避免了类的膨胀。
  3. 高灵活性
    • 可以灵活地为不同的对象选择不同的装饰器进行组合。

缺点

  1. 增加系统复杂性
    • 过多的装饰器可能使系统变得复杂,难以理解。
  2. 装饰器的顺序问题
    • 装饰器的顺序会影响最终对象的行为。

适用场景

  • 动态地给一个对象添加功能,例如为一个对象添加不同的用户界面样式、不同的服务功能。
  • 避免使用继承,需要在运行时动态地扩展功能。

总结

装饰器模式是一种非常灵活的模式,能够动态地给对象添加新功能,避免了继承带来的问题。通过组合装饰器类,能够灵活地为对象组合不同的功能,在很多场景中非常有用。



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

相关文章

浅谈云计算17 | 分布式存储

分布式存储 一、云存储系统结构模型1.1 存储层1.2 基础管理层1.3 应用接口层1.4 访问层 二、HDFS技术2.1 HDFS原理与架构2.1.1 架构组件2.1.2 数据存储与读取 2.2 HDFS特性分析2.2.1 容错性机制2.2.2 读写性能优化2.2.3 数据一致性保障 三、对等存储系统3.1 对等存储系统概述3.…

5套经典行业原型-含生鲜电商、旅游社交、O2O美食、汽车美容行业

近期反复有小伙伴找我&#xff0c;希望推荐产品资料&#xff0c;于是我把看过且认可的部分资料整理了一下&#xff0c;以后会持续分享给大家~~ 01 5套经典行业原型-含生鲜电商、旅游社交、O2O美食、汽车美容行业 目录内容介绍 流年烘焙-O2O美食-需求文档v2.docx 车蜜-O2O洗车-…

SpringBoot Maven 项目 pom 中的 plugin 插件用法整理

把 SpringBoot Maven 项目打包成 jar 文件时&#xff0c;我们通常用到 spring-boot-maven-plugin 插件。 前面也介绍过&#xff0c;在 spring-boot-starter-parent POM 和 spring-boot-starter POM 中都有插件的管理&#xff0c;现在我们就撸一把构建元素中插件的用法。 一、…

第三章、python中的对象、变量、标识符、作用域、引用(调用)及地址的概念(3.1-3.2)------内存地址、创建对象、对象的类型及对象的划分问题

第三章、python中的对象、变量、标识符、作用域、引用(调用)及地址的概念 本章讲述编程中对象、变量、地址的基本概念及其之间的关系,可迭代对象、可变对象、不可变对象的特点。

FastGPT结合New-api,遍享各类大模型

​​欢迎关注【AI技术开发者】 ​ 上文中&#xff0c;我们成功搭建了FastGPT服务和New-api服务 我们现在需要配置New-api服务&#xff0c;使用New-api来同时使用多个厂商的大模型服务&#xff0c;如豆包、通义千问、混元、文心一言、Kimi等模型 首先&#xff0c;我们需要修改…

Python毕业设计选题:基于python的酒店推荐系统_django+hadoop

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 酒店客房管理 客房类型管理 客房预定管理 用户…

Redis - 环境搭建

目录 在Ubuntu上安装Redis在Centos上安装RedisCentos7Centos8 版本&#xff1a;使用Redis5系列 操作系统&#xff1a;在Linux中进行安装&#xff08;Redis官方不支持Windows版本&#xff09; 在Ubuntu上安装Redis 更新软件包&#xff1a; sudo apt-get update搜索相关软件包…

深度学习中的张量 - 使用PyTorch进行广播和元素级操作

深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思&#xff1f; 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作&#xff0c;它作用于各自张量中的相应元素…