C++ 装饰器模式怎么用?

文章导读
Previous Quiz Next 装饰器 是一种 结构型设计模式,它允许我们在不改变或干扰现有对象结构的情况下为其添加新功能。它通过将该对象置于另一个包含新行为的特殊 包装对象 中,来为对象附加 新行为。
📋 目录
  1. 装饰器设计模式的组件
  2. C++ 中装饰器设计模式的实现
  3. Decorator 设计模式的优缺点
  4. 何时使用 Decorator 设计模式?
  5. Decorator 设计模式的现实世界应用
  6. 结论
A A

C++ 中的装饰器设计模式



Previous
Quiz
Next

装饰器 是一种 结构型设计模式,它允许我们在不改变或干扰现有对象结构的情况下为其添加新功能。它通过将该对象置于另一个包含新行为的特殊 包装对象 中,来为对象附加 新行为

让我们通过一个 示例 来详细理解。想象你有一个简单的 文本编辑器 应用程序,具有基本的文本功能,如编写、保存或编辑文本。现在,你的经理要求你添加一些新功能,如 拼写检查语法检查。如果你使用 Decorator Design Pattern,就可以轻松添加这些新功能,而无需更改文本编辑器的现有代码。你可以为拼写检查和语法检查创建独立的 decorator classes,这些类将围绕原始的文本编辑器类进行包装。

Decorator Design Pattern Example

装饰器设计模式的组件

Decorator Design Pattern四个主要组件,如下图所示。此外,client 是使用这些组件执行操作的一方。我们添加了两个

Components of Decorator Pattern

让我们详细了解这些组件 −

  • Component − 这是一个 interfaceabstract class,它为 concrete component 和 decorators 定义了共同的方法。在我们的示例中,这将是文本编辑器的接口。
  • Concrete Component − 这是实现 component 接口的类,代表我们要为其添加新功能的 原始对象。在我们的示例中,这将是基本的文本编辑器类。
  • Decorator − 这是一个 abstract class,它也实现 component 接口,并持有一个 component 对象的引用。decorator 类负责为 component 对象添加新功能。在我们的示例中,这将是文本编辑器的抽象 decorator 类。
  • Concrete Decorators − 这些是扩展 decorator 类的类,并实现 新功能。在我们的示例中,这些将是 spell checkergrammar checker 类,它们为文本编辑器添加各自的功能。

C++ 中装饰器设计模式的实现

之前,我们讨论了Decorator Design Pattern的组成部分。现在,让我们看看如何在 C++ 中实现它。

在这个实现中,我们将创建一个简单的Music Player应用程序,其中有一个可以播放音乐的basic music player。然后,我们将创建decorators,为音乐播放器添加新功能,如ShuffleRepeat

Music Player Example Decorator Design Pattern

实现装饰器设计模式的步骤

让我们看看如何在 C++ 中实现Decorator Design Pattern

  • 为音乐播放器创建一个Component接口。
  • 实现一个Concrete Component类,用于基本的音乐播放器。
  • 创建一个抽象的Decorator类,实现Component接口。
  • 实现两个具体的Decorator类,用于shufflerepeat功能。
  • 创建一个Client类来使用带有装饰器的音乐播放器。

装饰器设计模式的 C++ 代码

让我们看看音乐播放器应用的 Decorator Design Pattern 实现的 C++ 代码。

在这里,我们将使用之前讨论的所有Decorator Design Pattern组成部分。我们将为音乐播放器创建一个Component接口,一个用于基本音乐播放器的Concrete Component类,一个实现Component接口的抽象Decorator类,以及用于shufflerepeat功能的具体的Decorator类。

#include <iostream>
using namespace std;
// Component(组件)
class MusicPlayer {
public:
   virtual void play() = 0;
   virtual ~MusicPlayer() {}
};

// Concrete Component(具体组件)
class BasicMusicPlayer : public MusicPlayer {
public:
   void play() {
      cout << "Playing music..." << endl;
   }
};

// Decorator(装饰器)
class MusicPlayerDecorator : public MusicPlayer {
protected:
   MusicPlayer* player;
public:
   MusicPlayerDecorator(MusicPlayer* p) : player(p) {}
   virtual void play() {
      player->play();
   }
   virtual ~MusicPlayerDecorator() {
      delete player;
   }
};

// 用于 Shuffle 的具体装饰器
class ShuffleDecorator : public MusicPlayerDecorator {
public:
   ShuffleDecorator(MusicPlayer* p) : MusicPlayerDecorator(p) {}
   void play() {
      cout << "Shuffling playlist..." << endl;
      player->play();
   }
};

// 用于 Repeat 的具体装饰器
class RepeatDecorator : public MusicPlayerDecorator {
public:
   RepeatDecorator(MusicPlayer* p) : MusicPlayerDecorator(p) {}
   void play() {
      cout << "Repeating current song..." << endl;
      player->play();
   }
};

// Client(客户端)
int main() {
   MusicPlayer* player = new BasicMusicPlayer();
   MusicPlayer* shufflePlayer = new ShuffleDecorator(player);
   MusicPlayer* repeatShufflePlayer = new RepeatDecorator(shufflePlayer);

   cout << "Basic Music Player:" << endl;
   player->play();

   cout << "\nMusic Player with Shuffle:" << endl;
   shufflePlayer->play();

   cout << "\nMusic Player with Shuffle and Repeat:" << endl;
   repeatShufflePlayer->play();

   delete repeatShufflePlayer; // 这也将删除 shufflePlayer 和 player
   return 0;
}

以下是上述代码的输出

Basic Music Player:
Playing music...

Music Player with Shuffle:
Shuffling playlist...
Playing music...

Music Player with Shuffle and Repeat:
Repeating current song...
Shuffling playlist...
Playing music...

Decorator 设计模式的优缺点

下表突出了使用 Decorator Design Pattern 的优缺点 −

优点 缺点
允许在不修改现有代码的情况下添加新功能 可能导致大量小类
通过使用组合而非继承来促进代码复用 可能使代码变得更加复杂且难以理解。
通过将功能分解到单独的类中,遵循Single Responsibility Principle 由于多层包装,调试可能更加困难。
通过动态添加职责来提升灵活性 由于多层包装,可能存在性能开销
可以与其他design patterns结合用于更复杂的场景。 可能导致对象identityequality checks问题。

何时使用 Decorator 设计模式?

以下是一些您应该考虑使用 Decorator Design Pattern 的场景 −

  • 动态地为对象添加更多功能
  • 当您希望避免由于多个功能组合导致的类爆炸时。
  • 通过将功能分解到单独的类中,遵循Single Responsibility Principle
  • 为单个对象添加职责,而不影响同一类的其他对象。
  • 在运行时增强对象的行为

Decorator 设计模式的现实世界应用

下图展示了 Decorator 设计模式的一些现实世界应用 -

Real World Applications Decorator Design Pattern

结论

在本章中,我们学习了 Decorator Design Pattern,其组件、实现步骤以及一个 C++ 代码示例。我们还讨论了使用此模式的优缺点、何时使用它,以及一些现实世界应用。Decorator Design Pattern 是一个强大的工具,它允许我们在不改变现有对象结构的情况下添加新功能,从而使我们更容易维护和扩展程序代码。