C++ 策略模式怎么用?策略设计模式在C++中如何实现?

文章导读
Previous Quiz Next Strategy 设计模式 是一种简单而强大的方式,用于在有多种执行相同任务的方法时组织你的代码。它定义了一个算法族,将每个算法放在各自独立的 class 中,并允许你轻松地在它们之间切换。这意味着你可以不修改使用该算法的主代码的情
📋 目录
  1. Strategy 设计模式的关键组件
  2. C++ 中的 Strategy 设计模式实现
  3. Strategy 设计模式的优缺点
  4. Strategy 设计模式的现实世界示例
  5. 结论
A A

C++ 中的 Strategy 设计模式



Previous
Quiz
Next

Strategy 设计模式 是一种简单而强大的方式,用于在有多种执行相同任务的方法时组织你的代码。它定义了一个算法族,将每个算法放在各自独立的 class 中,并允许你轻松地在它们之间切换。这意味着你可以不修改使用该算法的主代码的情况下改变算法的行为。

例如,想象你有一个导航应用,它可以根据不同的偏好显示路线:最快路线最短路线最风景路线。使用 Strategy 设计模式,你可以为每种类型的路线创建一个单独的 class,并在需要时简单地在它们之间切换,而无需更改主应用的工作方式。

Strategy Design Pattern Illustration

Strategy 设计模式的关键组件

Strategy 设计模式 围绕几个主要部分构建,这些部分使代码更加灵活有组织易于维护。让我们逐一了解它们 −

  • Strategy 接口 − 它定义了一个公共方法,每个 strategy(或算法)都必须遵循。 它确保所有不同的 strategy 都可以以相同的方式使用,无论你选择哪一个。
  • 具体 Strategy − 这些是实现 Strategy 接口的实际 class。 每个都代表一种不同的算法或执行任务的方式。例如,一个 strategy 可能计算最快路线,而另一个则找到最风景路线。
  • Context − 这是使用其中一个 strategy 的主 class。 它保持对 Strategy 对象的引用,并要求它执行任务。Context 不关心使用的是哪个 strategy,它只知道可以对任何一个调用相同的方法。

简而言之,Strategy 设计模式 帮助你编写更容易更新更易阅读更易扩展 的代码。当出现一种新的做事方式时,你只需添加一个新的 strategy class,而无需重写现有代码。

C++ 中的 Strategy 设计模式实现

在本节中,我们将看到如何在 C++ 中实现 Strategy 设计模式,使用一个简单易懂的示例。我们将创建一个Context 类,它可以使用不同的策略来执行计算。 每个策略都将编写在自己的中,使程序足够灵活,以便在需要时在不同策略之间切换,而无需更改其余代码。

C++ 中实现 Strategy 设计模式的步骤

  • 定义 Strategy 接口 − 首先创建一个抽象类,定义算法的通用方法。这个接口就像一个蓝图,每个策略类都会遵循相同的结构。
  • 实现具体策略 − 创建独立的类,继承自 Strategy 接口,并提供算法的自己的版本。每个类将代表执行同一任务的不同方式
  • 创建 Context 类 − 这是将使用其中一个策略的主要类。 它持有一个 Strategy 对象的引用,并使用它来执行计算。Context 不关心使用的是哪个策略,它只是调用相同的方法。
  • 使用 Strategy 模式 − 在main 函数中,为 Context 和不同的 Strategy 类创建对象。展示 Context 如何动态切换策略,例如,从加法切换到乘法 — 无需重写 Context 本身中的任何逻辑。

通过遵循这些步骤,你将学会Strategy 设计模式如何帮助使你的代码更加简洁易于扩展更灵活,当你需要更改或添加新行为时。

Strategy 设计模式的 C++ 示例代码

下面是一个简单的 C++ 中 Strategy 设计模式的实现。在这个示例中,我们有一个 context 类,可以使用不同的策略来进行计算(加法和减法)。

#include <iostream>
using namespace std;

// Strategy 接口

class Strategy {
public:
   virtual int doOperation(int a, int b) = 0;
   virtual ~Strategy() {}
};

// 加法的具体策略

class Addition : public Strategy {
public:
   int doOperation(int a, int b) override {
      return a + b;
   }
};

// 减法的具体策略

class Subtraction : public Strategy {
public:
   int doOperation(int a, int b) override {
      return a -b;
   }
};

// Context 类

class Context {
private:
   Strategy* strategy;
public:
   Context(Strategy* strategy) : strategy(strategy) {}
   
   void setStrategy(Strategy* strategy) {
      this->strategy = strategy;
   }
   
   int executeStrategy(int a, int b) {
      return strategy->doOperation(a, b);
   }
};

int main() {
   Context* context = new Context(new Addition());
   cout << "10 + 5 = " << context->executeStrategy(10, 5) << endl;

   context->setStrategy(new Subtraction());
   cout << "10 -5 = " << context->executeStrategy(10, 5) << endl;

   delete context;
   return 0;
}

以上代码的输出如下 −

10 + 5 = 15
10 -5 = 5

Strategy 设计模式的优缺点

像大多数设计模式一样,Strategy 设计模式既有优点,也有缺点。理解这两方面有助于你决定在项目中是否真正值得使用它。

优点 缺点
该模式让你在程序运行时自由更改算法。 你无需编辑主类;只需将一种 strategy 切换为另一种, 这使得代码保持灵活易于适应 每个 strategy 都需要自己的class,这可能会增加项目中的文件数量。 在较大的应用中,这可能使代码库感觉更杂乱且更难导航。
由于每个算法都放在自己的class中,更新或修复它时不会影响代码的其他部分, 这变得容易得多。 这种分离使程序更整洁且更容易维护 对于小型或简单的程序,使用该模式可能会感觉工作量过大。 为简单功能创建多个 class 可能会使代码变得比必要时更复杂
Strategy 可以在程序的不同部分甚至其他项目中复用。 这有助于避免重复相同的逻辑,并保持代码更有组织 由于程序必须通过额外的层来访问 strategy 对象, 可能会产生少量的性能开销。 这通常很小,但在性能关键的应用中值得注意。

总体而言,Strategy 设计模式是一种实用整洁的方式,用于保持代码的灵活性易管理性。当你的程序需要在不同算法行为之间切换时,它特别有用,但对于非常简单的项目,坚持直接方法可能更好。

Strategy 设计模式的现实世界示例

Strategy 设计模式在许多软件程序中使用,以轻松更改某事物的运作方式。以下是一些它可以使用的简单示例 −

  • 支付系统中,例如在线购物应用,不同的支付方式如信用卡、PayPal 或加密货币可以分别编写在单独的 class 中。然后程序可以根据用户选择来决定使用正确的支付方式。
  • 在需要排序数据的程序中,不同的排序方法如 quicksort、mergesort 或 bubblesort 可以用作单独的 strategy。程序可以根据数据的大小来决定使用哪一种。
  • 文件压缩软件中,不同的压缩类型如 ZIP、RAR 或 TAR 可以分别编写。用户可以选择使用哪一种,而无需更改主程序。
  • 视频游戏中,不同的角色行为如攻击、防守或静止 可以各自作为独立的 strategy。游戏可以根据游戏过程中发生的情况在它们之间切换。
Strategy Design Pattern Applications Illustration

结论

在本章中,我们探讨了 Strategy 设计模式、其关键组件,以及它如何帮助使代码更灵活且更容易管理。我们还看到了该模式可以有效应用的现实世界示例。