【设计模式】【行为型模式(Behavioral Patterns)】之策略模式(Strategy Pattern)

devtools/2024/11/30 19:49:40/

1. 设计模式原理说明

策略模式(Strategy Pattern) 是一种行为设计模式,它允许你定义一系列算法,并将每个算法封装起来,使它们可以互换。策略模式让算法的变化独立于使用算法的客户。通过这种方式,客户端可以根据不同的情况选择不同的算法,而不需要修改其内部结构。

主要角色
  1. Context(上下文):使用某个策略类的对象。它维护着对Strategy对象的引用,用于在运行时切换策略。
  2. Strategy(策略接口):定义所有支持的算法的公共接口。Context使用这个接口来调用具体的策略。
  3. ConcreteStrategy(具体策略):实现了Strategy接口的具体算法。

2. UML 类图及解释

UML 类图
+------------------+                +-----------------------+
|      Context     |                |   Strategy Interface  |
|------------------|                |-----------------------|
| - strategy: Strategy |            | - execute(context): void |
|------------------|                +-----------------------+
| - setStrategy(strategy: Strategy) |                ^
| - performOperation()              |                |
+------------------+                +-----------------------+||v+---------------------------+| ConcreteStrategyA         ||--------------------------|| - execute(context): void  |+---------------------------+^|+---------------------------+| ConcreteStrategyB         ||--------------------------|| - execute(context): void  |+---------------------------+
类图解释
  • Context:维护对Strategy对象的引用,并提供一个方法performOperation()来执行策略。客户端通过这个方法来调用具体的策略。
  • Strategy:定义了所有支持的算法的公共接口。Context使用这个接口来调用具体的策略。
  • ConcreteStrategyA 和 ConcreteStrategyB:实现了Strategy接口的具体算法。客户端可以选择不同的具体策略来执行不同的算法。

3. 代码案例及逻辑详解

Java 代码案例
// 策略接口
interface Strategy {void execute();
}// 具体策略A
class ConcreteStrategyA implements Strategy {@Overridepublic void execute() {System.out.println("Executing strategy A");}
}// 具体策略B
class ConcreteStrategyB implements Strategy {@Overridepublic void execute() {System.out.println("Executing strategy B");}
}// 上下文
class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void setStrategy(Strategy strategy) {this.strategy = strategy;}public void performOperation() {strategy.execute();}
}// 客户端
public class Client {public static void main(String[] args) {Context context = new Context(new ConcreteStrategyA());context.performOperation(); // 输出: Executing strategy Acontext.setStrategy(new ConcreteStrategyB());context.performOperation(); // 输出: Executing strategy B}
}
C++ 代码案例
#include <iostream>// 策略接口
class Strategy {
public:virtual void execute() = 0;virtual ~Strategy() {}
};// 具体策略A
class ConcreteStrategyA : public Strategy {
public:void execute() override {std::cout << "Executing strategy A" << std::endl;}
};// 具体策略B
class ConcreteStrategyB : public Strategy {
public:void execute() override {std::cout << "Executing strategy B" << std::endl;}
};// 上下文
class Context {
private:Strategy* strategy;
public:Context(Strategy* strategy) : strategy(strategy) {}void setStrategy(Strategy* strategy) {this->strategy = strategy;}void performOperation() {strategy->execute();}~Context() {delete strategy;}
};// 客户端
int main() {Context context(new ConcreteStrategyA());context.performOperation(); // 输出: Executing strategy Acontext.setStrategy(new ConcreteStrategyB());context.performOperation(); // 输出: Executing strategy Breturn 0;
}
Python 代码案例
# 策略接口
class Strategy:def execute(self):raise NotImplementedError# 具体策略A
class ConcreteStrategyA(Strategy):def execute(self):print("Executing strategy A")# 具体策略B
class ConcreteStrategyB(Strategy):def execute(self):print("Executing strategy B")# 上下文
class Context:def __init__(self, strategy: Strategy):self._strategy = strategydef set_strategy(self, strategy: Strategy):self._strategy = strategydef perform_operation(self):self._strategy.execute()# 客户端
if __name__ == "__main__":context = Context(ConcreteStrategyA())context.perform_operation()  # 输出: Executing strategy Acontext.set_strategy(ConcreteStrategyB())context.perform_operation()  # 输出: Executing strategy B
Go 代码案例
package mainimport ("fmt"
)// 策略接口
type Strategy interface {execute()
}// 具体策略A
type ConcreteStrategyA struct{}func (c *ConcreteStrategyA) execute() {fmt.Println("Executing strategy A")
}// 具体策略B
type ConcreteStrategyB struct{}func (c *ConcreteStrategyB) execute() {fmt.Println("Executing strategy B")
}// 上下文
type Context struct {strategy Strategy
}func NewContext(strategy Strategy) *Context {return &Context{strategy: strategy}
}func (c *Context) SetStrategy(strategy Strategy) {c.strategy = strategy
}func (c *Context) PerformOperation() {c.strategy.execute()
}// 客户端
func main() {context := NewContext(&ConcreteStrategyA{})context.PerformOperation() // 输出: Executing strategy Acontext.SetStrategy(&ConcreteStrategyB{})context.PerformOperation() // 输出: Executing strategy B
}

4. 总结

策略模式 是一种行为设计模式,它允许你定义一系列算法,并将每个算法封装起来,使它们可以互换。这种模式的主要目的是在不改变客户端代码的情况下,通过不同的策略来实现不同的行为。

主要优点
  1. 算法可互换:可以在运行时动态地选择不同的算法,提高了灵活性。
  2. 职责分离:将算法的实现和使用算法的客户端分离,降低了耦合度。
  3. 易于扩展:增加新的策略非常容易,只需要实现策略接口即可。
主要缺点
  1. 增加了类的数量:每种策略都需要一个具体的类,可能会导致类的数量增多。
  2. 客户端需要了解所有策略:客户端需要知道所有的策略类,以便在运行时选择合适的策略。
适用场景
  • 当有多个相似的算法需要根据环境或条件动态选择时。
  • 当需要在运行时动态地改变对象的行为时。
  • 当类的行为由其子类决定时,可以考虑使用策略模式来避免大量的子类继承。
  • 当需要封装不同的算法或行为,并且这些算法或行为可以互换时。

http://www.ppmy.cn/devtools/138278.html

相关文章

服务器如何隐藏端口才能不被扫描?

在服务器上隐藏端口以避免被扫描&#xff0c;是一种增强安全性的措施。虽然完全隐藏端口不太可能&#xff08;因为网络通信本质上需要暴露端口&#xff09;&#xff0c;但可以通过一系列技术手段尽量降低端口被扫描或探测的可能性。以下是详细的实现方法&#xff1a; 1. 更改默…

pytest+allure生成报告显示loading和404

pytestallure执行测试脚本后&#xff0c;通常会在电脑的磁盘上建立一个临时文件夹&#xff0c;里面存放allure测试报告&#xff0c;但是这个测试报告index.html文件单独去打开&#xff0c;却显示loading和404, 这个时候就要用一些办法来解决这个报告显示的问题了。 用命令产生…

家庭事务管理微信小程序ssm+论文源码调试讲解

2系统关键技术 2.1 微信小程序 微信小程序&#xff0c;简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种全新的连接用户与服务的方式&#xff0c;可以快速访问、快速传播&#xff0c;并具有良好的使用体验。 小程序的主要开发语言是JavaScript&#xff0c;它与普…

netconf 代码架构

NETCONF&#xff08;Network Configuration Protocol&#xff09;是一种基于 XML 的网络配置管理协议&#xff0c;主要用于在网络设备之间进行配置管理、状态监控和操作。它被设计为一种可扩展的协议&#xff0c;并且在自动化网络管理中扮演着重要角色。NETCONF 通过安全的通信…

汽车软件单元测试的重要性

随着自动驾驶技术的迅猛发展&#xff0c;汽车行业面临着前所未有的挑战与机遇。自动驾驶汽车的普及不仅改变了人们的出行方式&#xff0c;也对汽车软件的安全性和可靠性提出了更高的要求。然而&#xff0c;近年来频发的汽车事故往往与软件设计和测试不充分密切相关&#xff0c;…

【算法】欧几里得与拓展欧几里得算法

目录 一、欧几里得算法 二、拓展欧几里得算法 2.1 裴蜀定理 2.2 拓展欧几里得算法 2.3 例题 三、线性同余方程 3.1 概念 3.2 例题 一、欧几里得算法 欧几里得算法又称辗转相除法&#xff0c;可用于求解两个数的最大公约数 其思路&#xff1a; gcd(a, b) gcd(b, a%b…

cuda安装步骤

查看本地cuda版本号 由于tensorflow2.4.1相对应的cuda版本是11.0 我们anaconda里面的虚拟环境里面装的是11.0版本&#xff0c;但是我们电脑自身的cuda版本却不是11.0版本&#xff0c;版本较低 可以在命令行查看自己电脑的NVIDIA相关信息&#xff0c;查看本地cuda版本号 先cd…

Docker Desktop Engine Stopped原因分析(docker桌面停止)WSL没装或没更新

文章目录 1. Docker 服务未启动2. 资源不足3. Docker 配置问题4. Hyper-V 或 WSL 2 配置问题好像确实windows没装WSL&#xff0c;执行命令安装一下&#xff08;好像需要代理&#xff1f;&#xff09;&#xff1a;果然装了这个后&#xff0c;再启动docker desktop&#xff0c;就…