%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later %% # 策略模式(Strategy) 「策略模式」:**对完成某一特定任务或行为的算法进行==抽象==(作为接口/抽象类)**,并**将这类算法的不同具体实现封装为独立的类**,通过**接口类实现==多态**==,从而使得**可以动态切换不同的算法实现对象**。 策略模式的构成: - **==策略接口==**(Strategy Interface):**==接口/抽象类==**,其代表一个**抽象算法族**,而所有**具体的、不同的算法实现类**则**实现该接口或继承该抽象类** - **==具体策略==**(Concrete Strategy):为策略接口提供各种不同的**具体实现**的**具体策略类** - **==上下文==**(Context)一个**上下文类**, - 其**持有一个==策略对象==的 "==引用"(指针)==**。上下文类**将所其需执行的任务 "==委派==" 给该策略对象** - 其**提供 `setStrategy()`** 方法**供外部设置、更改具体策略**。 > [!NOTE] > - "**具体策略**" 对上下文类透明,由**外部在运行时传递给上下文类**。 > - 上下文类仅通过 "**抽象策略类提供的通用接口**" 来触发策略执行。 ![[_attachment/02-开发笔记/16-设计模式/0-MOC-设计模式.assets/IMG-0-MOC-设计模式-B4F442A75A61C8536343B92CC3941A2C.png|459]] ## 优缺点 - 优点: - **易于扩展**,增加新的算法时只需**继承抽象策略类**,实现一个**新的具体策略类**即可 - 缺点: - **客户端**必须要知道**所有的策略**,以便在**使用时按需实例化具体策略**并传递给「**上下文实例**」 <br><br><br> # 示例场景 ##### 示例一:人物角色及其不同武器装备下的攻击行为 > 参见 [^1] > [!example] > ![[_attachment/02-开发笔记/16-设计模式/0-MOC-设计模式.assets/IMG-0-MOC-设计模式-0EC39396A4D400A61E44B9A381D78EC0.png|615]] > [!example] > ![[_attachment/02-开发笔记/16-设计模式/0-MOC-设计模式.assets/IMG-0-MOC-设计模式-A158F6170416161B243D681222D3441A.png|770]] #### 示例二:路径规划策略 > 参见[^2] > [!example] > ![[_attachment/02-开发笔记/16-设计模式/0-MOC-设计模式.assets/IMG-0-MOC-设计模式-37C2953643EABF475902FFAE7841F90B.png|549]] <br><br> # 示例代码 ```cpp #include <iostream> #include <memory> // 策略接口类(抽象类) class Strategy { public: virtual void execute() const = 0; // 纯虚函数 virtual ~Strategy() = default; // 虚析构函数 }; // 具体策略类A class ConcreteStrategyA : public Strategy { public: void execute() const override { std::cout << "Called ConcreteStrategyA execute method" << std::endl; } }; // 具体策略类B class ConcreteStrategyB : public Strategy { public: void execute() const override { std::cout << "Called ConcreteStrategyB execute method" << std::endl; } }; // 具体策略类C class ConcreteStrategyC : public Strategy { public: void execute() const override { std::cout << "Called ConcreteStrategyC execute method" << std::endl; } }; // 上下文类 class Context { private: // 持有一个策略接口类的指针, 调用该类提供的接口来执行具体策略 // 策略接口类应用了"多态", 可指向任意不同的具体策略类. std::unique_ptr<Strategy> strategy_; public: explicit Context(std::unique_ptr<Strategy> strategy) : strategy_(std::move(strategy)) {} // 设置具体的策略实例对象 void setStrategy(std::unique_ptr<Strategy> strategy) { this->strategy_ = std::move(strategy); } // 执行策略 void execute() const { // 调用策略接口类的方法. // 这里体现了运行时多态, 实际执行的是具体策略类实现的方法. strategy_->execute(); } }; int main() { // 创建上下文对象, 并传入具体策略类实例 // 使用策略A Context context(std::make_unique<ConcreteStrategyA>()); context.execute(); // 调用具体策略类A的方法 // 更改为策略B context.setStrategy(std::make_unique<ConcreteStrategyB>()); context.execute(); // 调用具体策略类B的方法 // 更改为策略C context.setStrategy(std::make_unique<ConcreteStrategyC>()); context.execute(); // 调用具体策略类C的方法 return 0; } ``` <br><br> # 参考资料 # Footnotes