当前位置: 首页 > news >正文

设计模式(三)

设计模式(三)

某些情况,可能会过度地使用继承来扩展对象的功能;

由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;

随着子类增多, 各种子类的组合会导致更多子类的膨胀

需要使用对象功能的扩展,能够根据需要来动态地实现,避免扩展功能的增多带来的子类膨胀

装饰者模式

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式通过创建一个包装对象(装饰者)来包裹真实的对象,并提供增强的功能

eg:咖啡

如果我们想要为咖啡添加不同的调料(如糖、牛奶、巧克力等),我们可能需要为每种可能的组合创建一个类

class Coffee {
public:virtual std::string getDescription() const = 0;virtual double cost() const = 0;
};class SimpleCoffee : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee";}double cost() const override {return 10.0;}
};class CoffeeWithMilk : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee with Milk";}double cost() const override {return 12.0; // Coffee cost + Milk cost}
};class CoffeeWithSugar : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee with Sugar";}double cost() const override {return 11.0; // Coffee cost + Sugar cost}
};// ... 更多组合类 ...

这种无脑的使用继承,会造成子类过于繁多,臃肿;

解决方法是:

通过组合来增加灵活性,继承是编译时静态决定的;而组合则是运行时,动态地添加或更换组件

​ 继承会导致子类和父类紧密的耦合,父类若变,子类有可能都受影响

​ 组合可以重用 不同类的对象和功能

使用装饰者模式:

创建一个装饰者基类,然后为每种调料创建一个装饰者类

class Coffee {
public:virtual std::string getDescription() const = 0;virtual double cost() const = 0;virtual ~Coffee() {}
};class SimpleCoffee : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee";}double cost() const override {return 10.0;}
};// Decorator
class CoffeeDecorator : public Coffee {
protected:Coffee* coffee;public:CoffeeDecorator(Coffee* coffee) : coffee(coffee) {}std::string getDescription() const override {return coffee->getDescription();}double cost() const override {return coffee->cost();}
};// Concrete Decorators
class Milk : public CoffeeDecorator {
public:Milk(Coffee* coffee) : CoffeeDecorator(coffee) {}std::string getDescription() const override {return CoffeeDecorator::getDescription() + ", Milk";}double cost() const override {return CoffeeDecorator::cost() + 2.0; // Milk cost}
};class Sugar : public CoffeeDecorator {
public:Sugar(Coffee* coffee) : CoffeeDecorator(coffee) {}std::string getDescription() const override {return CoffeeDecorator::getDescription() + ", Sugar";}double cost() const override {return CoffeeDecorator::cost() + 1.0; // Sugar cost}
};// ... 更多装饰者类 ...

这样就可以动态的添加调料到咖啡中

int main() {Coffee* myCoffee = new SimpleCoffee();std::cout << myCoffee->getDescription() << " - $" << myCoffee->cost() << std::endl;myCoffee = new Milk(myCoffee);std::cout << myCoffee->getDescription() << " - $" << myCoffee->cost() << std::endl;myCoffee = new Sugar(myCoffee);std::cout << myCoffee->getDescription() << " - $" << myCoffee->cost() << std::endl;// Clean updelete myCoffee;return 0;
}/*输出:Simple Coffee - $10Simple Coffee, Milk - $12Simple Coffee, Milk, Sugar - $13
*/

可以看到,在装饰者类中

既继承了父类,又定义了父类;即:is-a has-a

同时继承父类,组合子类

通常这种继承父类,又再类中定义了父类,八成是装饰者模式


http://www.mrgr.cn/news/59931.html

相关文章:

  • 【在WindoWs 10 cmd查询管理目录下所有文件及其相对位置】
  • 1U服务器和Hyper-V虚拟机使用记录
  • JavaScript正则表达式利器:exec()方法深度解析与应用实例
  • dy a_bogus 1.0.1.17 最新版本补环境 分析
  • 边缘计算路由网关R40钡铼技术3LAN口1WAN口Modbus协议
  • 影刀RPA实战:常见实用功能指令
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21
  • 安装anacanda-学习笔记
  • 基于图神经网络的组合优化与推理(JML 2023)(未完)
  • linux指令笔记
  • 多线程——线程安全的集合类
  • QT 信号重载时的处理方法
  • 01.04、回文排序
  • 【C++】Map()函数
  • 【无标题】idea 一次性切换多个项目的分支
  • 【轻量级聊天应用】Vocechat本地服务器部署结合cpolar异地即时通讯
  • 龙芯+FreeRTOS+LVGL实战笔记(新)——13LVGL字体转换
  • 【程序员的逆袭】:在失业的阴影下寻找光明
  • linux系统安全:开源的反病毒工具ClamAV的安装配置使用和维护介绍
  • 如何解决RabbitMQ消息的重复消费问题
  • JavaScript 数据类型与操作
  • LeetCode算法(哈希)
  • osgEarth中显示XYZ影像服务
  • C++STL之stack
  • Python条形图 | 指标(特征)重要性图的绘制
  • 高效网络自动化:Python在网络基础中的应用