【C++设计模式】详解装饰模式

这篇具有很好参考价值的文章主要介绍了【C++设计模式】详解装饰模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2023年8月31日,周四上午

这是我目前碰到的最难的设计模式.....

非常难以理解而且比较灵活多半,学得贼难受,写得贼费劲.....

2023年8月31日,周四晚上19:48

终于写完了,花了一天的时间来学习装饰模式和写这篇博客。

虽然基本上把我今天的收获都写下来了,

但感觉写得还是不够好,有很多东西没有表达出来、表达清楚,

以后有空再更新吧....


目录

  • 概述
  • 装饰模式的含义
  • 使用装饰模式的好处
  • 为什么需要装饰模式
  • 什么时候使用装饰模式
  • 情景
  • 标准的装饰模式
  • 装饰模式的主要特征
  • 标准装饰模式程序示例
  • 我对标准装饰模式的思考
  • 使用标准装饰模式来写的示例程序

概述

装饰模式的含义

装饰模式是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。

使用装饰模式的好处

  • 可以动态地给对象添加责任,扩展对象功能。
  • 相比继承,装饰模式使用对象组合而不是继承来扩展功能。更加灵活。
  • 装饰模式支持开闭原则,扩展对象不修改其代码。

为什么需要装饰模式

  1. 动态扩展功能:装饰模式允许在运行时动态地给对象添加新的功能,而不需要修改原始对象的代码。这样可以避免类的继承层次的爆炸性增长,同时也更加灵活和可扩展。
  2. 单一职责原则:装饰模式通过将功能分散到多个装饰类中,每个装饰类只关注特定的功能,遵循了单一职责原则,使得代码更加清晰、可维护。
  3. 开放-封闭原则:装饰模式支持对现有代码的扩展,而不需要修改已有的代码,符合开放-封闭原则。这样可以避免因为修改现有代码而引入潜在的风险和错误。

什么时候使用装饰模式

  1. 需要在不改变现有对象结构的情况下,给对象增加新的功能或责任。
  2. 需要动态地给对象添加功能,并且这些功能可以组合和排列。
  3. 需要扩展一个类的功能,但是使用继承会导致类的继承层次过于庞大或不可行。
  4. 需要在运行时动态地给对象添加功能,而不是在编译时静态地确定功能。

情景

假设我有一个类Xxx,需要给它添加加法功能和减法功能,

但是由于这个类已经很复杂了、而且继承的层次已经很深了,

我不想改动里面的代码,也不想再多弄一个子类,那么怎么添加这两个功能呢?

class Xxx:public Ppp{
public:
	void func1();
	void func2();
	void func3();
	void func4();
	void func5();
	void func6();
	void func7();
};

在这种情况下,可以使用装饰模式来添加这两个功能,

因为这样既不用改动类内部代码,也不用再多弄一个子类。

// 原始类
class Xxx :public Ppp{
public:
  void func1() { /* 原始功能1的实现 */ }
  void func2() { /* 原始功能2的实现 */ }
  // ... 其他原始功能的实现
  void func7() { /* 原始功能7的实现 */ }
};

// 装饰类 - 加法功能
class AddDecorator : public Xxx {
private:
  Xxx* component;

public:
  AddDecorator(Xxx* component) : component(component) {}

  void func1() override {
    component->func1();
    // 加法功能的实现
  }
};

// 装饰类 - 减法功能
class SubtractDecorator : public Xxx {
private:
  Xxx* component;

public:
  SubtractDecorator(Xxx* component) : component(component) {}

  void func2() override {
    component->func2();
    // 减法功能的实现
  }
};

int main() {
  Xxx* xxx = new Xxx();

  // 使用加法功能的装饰类
  Xxx* xxxWithAddition = new AddDecorator(xxx);
  xxxWithAddition->func1();

  // 使用减法功能的装饰类
  Xxx* xxxWithSubtraction = new SubtractDecorator(xxx);
  xxxWithSubtraction->func2();

  delete xxxWithSubtraction;
  delete xxxWithAddition;
  delete xxx;

  return 0;
}

注意,这并不是一个完整的装饰模式,但有助于理解装饰模式的作用。

标准的装饰模式

装饰模式的主要特征

  • 有一个抽象构件类,定义对象的接口。
  • 具体构件类实现抽象构件类。
  • 有一个装饰类继承抽象构件类,包含抽象构件类的对象引用。
  • 装饰类可以调用父类接口实现扩展功能。

标准装饰模式程序示例

#include <iostream>

// 抽象构件类
class Component {
public:
  virtual void func() = 0;
};

// 具体构件类
class ConcreteComponent : public Component {
public:
  void func() override {
    std::cout << "具体构件的操作" << std::endl;
  }
};

// 装饰类
class Decorator : public Component {
protected:
  Component* component;

public:
  Decorator(Component* component) : component(component) {}

  void func() override {
    if (component != nullptr) {
      component->func();
    }
  }
};

// 具体装饰类A
class ConcreteDecoratorA : public Decorator {
public:
  ConcreteDecoratorA(Component* component) : Decorator(component) {}

  void addedBehavior() {
    std::cout << "具体装饰类的附加行为A" << std::endl;
  }

  void func() override {
    Decorator::func();
    addedBehavior();
  }
};

// 具体装饰类B
class ConcreteDecoratorB : public Decorator {
public:
  ConcreteDecoratorB(Component* component) : Decorator(component) {}

  void addedBehavior() {
    std::cout << "具体装饰类的附加行为B" << std::endl;
  }

  void func() override {
    Decorator::func();
    addedBehavior();
  }
};

int main() {
  Component* component = new ConcreteComponent();
  
  //用decoratedComponentA修饰component
  Component* decoratedComponentA = new ConcreteDecoratorA(component);
  //用decoratedComponentB修饰被decoratedComponentA修饰过的component
  Component* decoratedComponentB = new ConcreteDecoratorB(decoratedComponentA);
  
  decoratedComponentB->func();
  
  //要记得释放申请的堆内存
  delete decoratedComponentA;
  delete decoratedComponentB;
  delete component;

  return 0;
}

【C++设计模式】详解装饰模式,# C++设计模式,设计模式

我对标准装饰模式的思考

装饰模式是怎么实现的不改动类原来的代码和结构就增加新的功能的?
装饰器是如何装饰具体构建类的?

他们有同一个抽象父类
这意味这什么?它们都会有抽象构件类的纯虚函数

装饰器需要引入抽象构件类
能引入抽象构件类,意味传入具体构件类对象后,只能调用其中抽象构件类有的方法
装饰器会重写父类的方法,并在重写的方法里面调用具体构件类的方法

具体装饰器有自己独特的成员和方法
具体装饰器会把具体构件类装入
具体装饰器会重写抽象装饰器的方法,并在重写的方法里面调用父类的方法和自己独特的方法
不管怎样,具体装饰类必须引入抽象构件类并传入具体构件类对象

装饰模式的核心在于重写?
重写的时候加入额外的方法

具体构件类需要实现抽象构件类的纯虚函数,否则无法被创建

装饰器的作用是什么?
引入具体构件类
在重写方法中调用具体构件类的方法

抽象构件类的作用是什么?

具体构件类的作用是什么?
定义最基础的功能

具体装饰器的作用是什么?
写额外的功能,然后通过重写方法加入额外的功能

使用标准装饰模式来写的示例程序

#include<iostream>

class Product{
public:
	virtual void buy()=0;
};

class Computer:public Product{
public:
	void buy ()override{
		std::cout<<"买了一台电脑"<<std::endl;
	}
};

class Decorate:public Product{
private:
	Product *product;
public:
	Decorate(Product *product):product(product){};
	
	void buy() override{
		if(product!=nullptr){
			product->buy();
		}
	}
};

class Mouse:public Decorate{
public:
	Mouse(Product *product):Decorate(product){};
	
	void buy() override{
		Decorate::buy();
		std::cout<<"又买了鼠标"<<std::endl;
	}
};

class KeyBoard:public Decorate{
public:
	KeyBoard(Product *product):Decorate(product){};
	
	void buy() override{
		Decorate::buy();
		std::cout<<"又买了键盘"<<std::endl;
	}
};

int main(){
	Product *computer=new Computer();
	Mouse *mouse=new Mouse(computer);
	KeyBoard *keyBoard=new KeyBoard(mouse);
	keyBoard->buy();
}

【C++设计模式】详解装饰模式,# C++设计模式,设计模式文章来源地址https://www.toymoban.com/news/detail-687601.html

到了这里,关于【C++设计模式】详解装饰模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——装饰器模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。 这种模式创建了一个装饰类,用来包装原有的

    2024年02月10日
    浏览(37)
  • 【设计模式】-装饰器模式

    在软件开发中,经常有需求对已有的对象进行功能的扩展,但是传统的继承方式会导致类的数量快速增多,且难以维护。为了解决这个问题,装饰器模式应运而生。 装饰器模式是一种结构型设计模式,它可以在运行时动态地将新的行为附加到对象上,而不改变其结构。这种方

    2024年02月14日
    浏览(34)
  • 【设计模式】装饰器模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。 这种模式创建了一个装饰类,用来包装原有的

    2024年02月13日
    浏览(37)
  • 设计模式--装饰者模式

    (1) 可乐种类/单品可乐 :BaiShiCola(百事可乐) FeiChangCola(非常可乐) CoCola(可口可乐) (2) 调料/附品: Milk  Chocolate (3) 要求在扩展新的可乐种类时 要具有良好的扩展性 改动方便 维护方便 (4) 使用OO的来就算不同之类可乐的费用 客户可以点单品可乐 也可以单品可乐+调料组合 方案1 

    2024年02月02日
    浏览(39)
  • 设计模式——装饰者模式

    更多内容,前往 IT-BLOG 现实生活中常常需要给某类产品动态增加新的功能,如:给面条各种调味品。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成一些核心功能。但在不改变其架构的情况下,可以动态地扩展其功能。所以这些都可以采用装饰模式来实

    2024年02月22日
    浏览(32)
  • 设计模式(3)装饰模式

    一、介绍: 1、应用场景:把所需的功能按正确的顺序串联起来进行控制。动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是

    2024年02月13日
    浏览(38)
  • 设计模式-装饰器模式

    装饰者模式的定义为:动态的给一个对象添加其它功能。 从扩展性来说,这种方式比继承更有弹性,更加灵活,装饰者模式也体现了开闭原则(OCP)。 星巴克咖啡订单项目(咖啡馆) : 1)咖啡种类/单品咖啡: Espresso(意大利浓咖啡)、ShortBlack、Decaf(无因咖啡)、LongBlack(美式咖啡) 2)

    2024年02月06日
    浏览(38)
  • Java设计模式-装饰模式

    装饰模式在Java领域是一种常见的设计模式,它能够在不改变对象原有结构的情况下,动态地为对象添加新的功能。它通过封装原有对象,在运行时动态地为对象添加新的行为或者修改原有行为,以扩展对象的功能。这种方式避免了继承的静态特性,让对象的行为可以根据需要

    2024年02月04日
    浏览(41)
  • 【前端设计模式】之装饰模式

    装饰模式(Decorator Pattern)是一种结构型设计模式,它允许在不改变原有对象结构的情况下,动态地给对象添加额外的功能。装饰模式通过创建一个包装器(装饰器)来包裹原有对象,并在保持接口一致性的前提下,增加新的行为或修改原有行为。 继承或实现相同的接口 :装

    2024年02月09日
    浏览(34)
  • 设计模式7:装饰者模式

    官方说法:装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。 个人理解:原始接口功能不足,需要添加新方法,但是别的地方已经实现了原始接口,所以原始接口又不能直接添加方法。这时候可以采用持有原始类对象,并且添加新方法

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包