%%
# 纲要
> 主干纲要、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