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

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.mzph.cn/pingmian/62442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工程企业如何做好成本控制?该如何入手?

工程企业的成本控制是企业管理中的核心工作&#xff0c;其直接关系到项目的盈利能力和市场竞争力。以下从几个关键方向阐述如何入手做好成本控制&#xff1a; 一、明确成本控制目标 成本控制的目标不仅是减少支出&#xff0c;更重要的是保证项目质量和工期&#xff0c;避免因低…

多项式加法运算的链表实现

多项式加法运算的链表实现 主要思路&#xff1a;相同指数的项系数相加&#xff0c;其余部分进行拷贝。 两个多项式分别使用单链表实现&#xff0c;链表的每一个节点的结构为&#xff1a;系数、指数、下一个节点的地址。 链表节点按照指数递减顺序排列。 一句话&#xff1a;…

【N 卡 掉驱动 Driver 】NVML ERROR: Driver Not Loaded

问题描述 输入 nvitop 时报错 NVML ERROR: Driver Not Loaded&#xff0c;重启问题依旧存在。 问题解决-重新下载驱动 进入官网选择合适自己的驱动版本 https://www.nvidia.cn/geforce/drivers/ 根据个人情况搜索后&#xff0c;选择最新的 Driver 进行下载&#xff0c;如果希…

uniapp H5支付宝支付

1、scheme支付 uniapp scheme打开支付宝H5调起支付_支付宝scheme链接-CSDN博客 2、链接地址支付 location.href res.resultData.pay_info; 3、form表单支付 const divForm document.getElementById(divForm); if (divForm) {document.body.removeChild(divForm); } cons…

杭州网世一站式网络解决方案,助力安邦护卫网络升级改造

随着信息技术的不断进步&#xff0c;浙江台州安邦护卫有限公司现有的网络设备已无法满足其日益增长的业务需求。网络性能瓶颈、安全隐患和管理复杂性等问题逐渐凸显&#xff0c;严重影响了企业的运营效率和服务质量。为了解决这些问题&#xff0c;浙江台州安邦护卫有限公司决定…

IIC和SPI的时序图

SCL的变化快慢决定了通信速率&#xff0c;当SCL为低电平的时候&#xff0c;无论SDA是1还是0都不识别&#xff1a; ACK应答&#xff1a;当从设备为低电平的时候识别为从设备有应答&#xff1a; 谁接收&#xff0c;谁应答&#xff1a; 起始位和停止位&#xff1a; IIC的时序图&am…

C底层 函数栈帧

文章目录 一&#xff0c;什么是寄存器 二&#xff0c;栈和帧 前言 我们在学习c语言程序的时候&#xff0c;是不是有很多的疑问&#xff0c;如 1&#xff0c;为什么形参不可以改变实参 2&#xff0c;为什么我们编写程序的时候会出现烫烫烫......这个乱码 3&#xff0c;那些局…

全桥LLC变换器原理及MATLAB仿真模型

“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 主电路拓扑 全桥LLC 谐振变换器主电路拓扑结构图。图中S1 &#xff5e; S4为功率开关管&#xff0c; D1 &#xff5e; D4为功率开关管的体二极管&#xff0c; C1 &#xff5e; C4 为功率开关管的寄生电容。谐振电感r…

TavilySearchResults报错

报错 pydantic_core._pydantic_core.ValidationError: 1 validation error for TavilySearchAPIWrapper Value error, Did not find tavily_api_key, please add an environment variable TAVILY_API_KEY which contains it, or pass tavily_api_key as a named parameter. …

物料理解笔记·蓝白段子线·端子线座子焊接反了怎么处理!!!

目录 蓝白端子排线 端子线座子焊接错了怎么办 端子线如何拆线 编写不易&#xff0c;请勿搬运&#xff0c;仅供学习&#xff0c;感谢理解 蓝白端子排线 蓝白端子排线&#xff0c;这种端子线常用与编码电机的接线&#xff0c;或者在板子上通过提供段子线的接口&#xff0c;通…

shell(8)until循环以及函数基本创建

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

51c自动驾驶~合集35

我自己的原文哦~ https://blog.51cto.com/whaosoft/12206500 #纯视觉方案的智驾在大雾天还能用吗&#xff1f; 碰上大雾天气&#xff0c;纯视觉方案是如何识别车辆和障碍物的呢&#xff1f; 如果真的是纯纯的&#xff0c;特头铁的那种纯视觉方案的话。 可以简单粗暴的理解为…

Python中的23种设计模式:详细分类与总结

设计模式是解决特定问题的通用方法&#xff0c;分为创建型模式、结构型模式和行为型模式三大类。以下是对每种模式的详细介绍&#xff0c;包括其核心思想、应用场景和优缺点。 一、创建型模式&#xff08;Creational Patterns&#xff09; 创建型模式关注对象的创建&#xff0…

【ArcGIS Pro实操第11期】经纬度数据转化成平面坐标数据

经纬度数据转化成平面坐标数据 数据准备ArcGIS操作步骤-投影转换为 Sinusoidal1 投影2 计算几何Python 示例 另&#xff1a;Sinusoidal (World) 和 Sinusoidal (Sphere) 的主要区别参考 数据准备 数据投影&#xff1a; 目标投影&#xff1a;与MODIS数据相同&#xff08;Sinu…

Python3 pip

pip 是 Python 包管理工具&#xff0c;该工具提供了对 Python 包的查找、下载、安装、卸载的功能。 软件包也可以在 https://pypi.org/ 中找到。 目前最新的 Python 版本已经预装了 pip。 注意&#xff1a;Python 2.7.9 或 Python 3.4 以上版本都自带 pip 工具。 如果没有安…

docker搭建socks5代理

准备工作 VPS安全组/策略放行相应端口如启用了防火墙&#xff0c;放行相应端口 实际操作 我们选用“历史悠久”的Dante socks5 代理服务器&#xff0c;轻量、稳定。Github也有对dante进行进一步精简的镜像&#xff0c;更为适宜。github项目地址如下&#xff1a; https://gi…

【Leecode】Leecode刷题之路第62天之不同路径

题目出处 62-不同路径-题目出处 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 62-不同路径-官方解法 方法1&#xff1a;动态规划 思路&#xff1a; 代码示例&#xff1a;&#xff08;Java&…

如何写一份优质技术文档

作者简介&#xff1a; 本文作者拥有区块链创新专利30&#xff0c;是元宇宙标准化工作组成员、香港web3标准工作组成员&#xff0c;参与编写《数据资产确权与交易安全评价标准》、《链接元宇宙&#xff1a;应用与实践》、《香港Web3.0标准化白皮书》等标准&#xff0c;下面提供…

【Git】Git 完全指南:从入门到精通

Git 完全指南&#xff1a;从入门到精通 Git 是现代软件开发中最重要的版本控制工具之一&#xff0c;它帮助开发者高效地管理项目&#xff0c;支持分布式协作和版本控制。无论是个人项目还是团队开发&#xff0c;Git 都能提供强大的功能来跟踪、管理代码变更&#xff0c;并保障…

系统手势导航-虚拟导航切换

问题讨论-需求场景 何为手势和物理按键、虚拟导航 Android11 开始支持了手势操作&#xff0c;如大家目前手机基本上都是手势操作形式&#xff1b;早期都是物理按键或者虚拟按键的操作。 手势导航和虚拟导航如何选择 系统层面&#xff1a;设置->系统->手势->手势切…