一、策略模式简介

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式让算法独立于使用它的客户而变化,属于对象行为型模式。其核心思想是将算法的定义与使用分离,通过接口或抽象类来定义算法族,具体算法实现由具体策略类完成,客户端可以根据需要选择合适的策略。

二、策略模式的结构

  1. 抽象策略(Strategy)角色:这是一个抽象类或接口,定义了算法的公共接口,声明了算法的方法,所有具体策略类都需实现该接口或继承该抽象类。它为上下文角色提供一个统一的算法调用接口。
  2. 具体策略(Concrete Strategy)角色:实现了抽象策略接口或继承了抽象策略类,包含具体的算法实现。可以有多个具体策略类,每个类实现不同的算法,它们之间可以相互替换。
  3. 环境(Context)角色:持有一个对抽象策略角色的引用,负责与具体策略对象交互,它可以在运行时动态地更换策略对象,从而改变其行为。客户端通过环境角色来间接调用具体策略的算法方法。

三、策略模式的实现步骤

  1. 定义抽象策略接口或抽象类,声明算法方法。
  2. 创建具体策略类,实现抽象策略接口或继承抽象策略类,提供具体的算法实现。
  3. 构建环境类,包含一个抽象策略类型的成员变量,提供设置策略的方法,并通过该成员变量调用策略的算法方法。
  4. 客户端根据需要创建具体策略对象,并将其设置到环境对象中,然后调用环境对象的方法来执行相应的算法。

四、策略模式的优缺点

优点:
  1. 算法的可扩展性强:可以方便地增加新的策略,符合开闭原则。新的策略只需实现抽象策略接口或继承抽象策略类,无需修改现有代码。
  2. 避免使用多重条件判断:将算法封装在独立的策略类中,客户端通过选择不同的策略来执行不同的算法,避免了在代码中使用大量的条件判断语句,使代码更加简洁、清晰。
  3. 提高代码的可维护性:每个策略类都专注于实现一种算法,职责单一,易于理解和维护。当算法需要修改或优化时,只需修改相应的策略类,不会影响其他代码。
缺点:
  1. 增加了类的数量:每增加一个策略就需要增加一个具体策略类,当策略较多时,会导致系统中类的数量增加,增加系统的复杂性。
  2. 客户端需要了解所有策略:客户端需要知道所有的策略类,以便根据需要选择合适的策略。这增加了客户端的负担,同时也可能暴露策略的实现细节。
  3. 策略类之间可能相互依赖:在某些情况下,不同的策略之间可能存在依赖关系,这会增加系统的复杂性,并且可能导致策略之间的耦合度过高。

五、策略模式的应用场景

  1. 当存在多个相关的算法或行为,并且希望在运行时动态地选择其中的一个时。例如,一个电商系统中,根据不同的促销活动,可能有多种计算商品价格的策略,如满减、折扣、赠品等,可以使用策略模式来封装这些计算价格的算法,在结算时根据当前的促销活动选择相应的策略。
  2. 当算法需要频繁变化或需要被客户端动态切换时。比如,一个图像处理软件中,有多种图像滤镜算法,用户可以根据自己的需求选择不同的滤镜效果,这时可以使用策略模式来实现滤镜算法的切换。
  3. 当不希望条件判断语句过多,希望通过将算法封装在独立的类中来实现算法的灵活切换时。在一些业务逻辑复杂的场景中,可能存在大量的条件判断来选择不同的算法或行为,使用策略模式可以将这些条件判断分散到各个策略类中,使代码更加简洁和易于维护。

六、策略模式的示例代码

以下是一个简单的Java示例,演示了策略模式的应用。假设有一个鸭子类,鸭子可以有不同的飞行行为,如正常飞行、不会飞行等,使用策略模式来实现鸭子的飞行行为。

// 抽象策略接口
interface FlyBehavior {void fly();
}// 具体策略类:正常飞行
class FlyWithWings implements FlyBehavior {@Overridepublic void fly() {System.out.println("使用翅膀飞行");}
}// 具体策略类:不会飞行
class FlyNoWay implements FlyBehavior {@Overridepublic void fly() {System.out.println("不会飞行");}
}// 环境类:鸭子
class Duck {private FlyBehavior flyBehavior;public void setFlyBehavior(FlyBehavior flyBehavior) {this.flyBehavior = flyBehavior;}public void performFly() {if (flyBehavior!= null) {flyBehavior.fly();} else {System.out.println("没有设置飞行行为");}}
}// 客户端代码
public class StrategyPatternExample {public static void main(String[] args) {Duck duck = new Duck();// 设置鸭子为正常飞行行为duck.setFlyBehavior(new FlyWithWings());duck.performFly();// 切换鸭子为不会飞行行为duck.setFlyBehavior(new FlyNoWay());duck.performFly();}
}

在上述示例中,FlyBehavior是抽象策略接口,FlyWithWingsFlyNoWay是具体策略类,实现了不同的飞行行为。Duck是环境类,持有一个FlyBehavior类型的成员变量,通过setFlyBehavior方法可以动态地设置鸭子的飞行行为,然后调用performFly方法来执行飞行行为。客户端可以根据需要创建不同的具体策略对象,并将其设置到鸭子对象中,从而实现鸭子飞行行为的动态切换。


总之,策略模式是一种非常实用的行为型设计模式,它可以使算法的定义与使用分离,提高代码的灵活性、可扩展性和可维护性。在实际开发中,当遇到需要动态选择算法或行为的场景时,可以考虑使用策略模式来解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87863.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87863.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/87863.shtml

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

相关文章

【BIOS+MBR 微内核手写实现】

本文基于BIOS+MBR的架构,从四部分讲解微内核是如何实现的: 1)搭建微内核编译调试环境 2)梳理微内核的代码结构:伪指令讲解 3)手写实现微内核框架,输出简单的字符串 4)讲解微内核启动阶段的具体运行过程 先完成内核工程创建,如下图 我们这里使用nasm风格的汇编编写,…

从C/C++迁移到Go:内存管理思维转变

一、引言 在当今高速发展的软件开发世界中,语言迁移已成为技术进化的常态。作为一名曾经的C/C开发者,我经历了向Go语言转变的全过程,其中最大的认知挑战来自内存管理模式的根本性差异。 我记得第一次接触Go项目时的困惑:没有析构函…

正确设置 FreeRTOS 与 STM32 的中断优先级

在裸机开发(非 RTOS)时,大多数 STM32 外设的中断优先级通常不需要手动配置,原因如下: ✅ 裸机开发中默认中断优先级行为 特点说明默认中断优先级为 0如果你不设置,STM32 HAL 默认设置所有外设中断为 0&…

EasyExcel之SheetWriteHandler:解锁Excel写入的高阶玩法

引言在 EasyExcel 强大的功能体系中,SheetWriteHandler 接口是一个关键的组成部分。它允许开发者在写入 Excel 的 Sheet 时进行自定义处理,为实现各种复杂的业务需求提供了强大的支持。通过深入了解和运用 SheetWriteHandler 接口,我们能够更…

Python单例模式魔法方法or属性

1.单例模式概念定义:单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只能有一个实例,并提供一个全局访问点来获取该实例。这种模式在需要控制资源访问、配置管理或协调系统操作时特别有用。核心特点:私有构造函数:防止外部通过…

【Kubernetes系列】Kubernetes 资源请求(Requests)

博客目录 引言一、资源请求的基本概念1.1 什么是资源请求1.2 请求与限制的区别 二、CPU 请求的深入解析2.1 CPU 请求的单位与含义2.2 CPU 请求的调度影响2.3 CPU 请求与限制的关系 三、内存请求的深入解析3.1 内存请求的单位与含义3.2 内存请求的调度影响3.3 内存请求的特殊性 …

大型语言模型中的自动化思维链提示

摘要 大型语言模型(LLMs)能够通过生成中间推理步骤来执行复杂的推理任务。为提示演示提供这些步骤的过程被称为思维链(CoT)提示。CoT提示有两种主要范式。一种使用简单的提示语,如“让我们一步一步思考”,…

Private Set Generation with Discriminative Information(2211.04446v1)

1. 遇到什么问题,解决了什么遇到的问题现有差分隐私生成模型受限于高维数据分布建模的复杂性,合成样本实用性不足。深度生成模型训练依赖大量数据,加入隐私约束后更难优化,且不保证下游任务(如分类)的最优解…

C++编程语言入门指南

一、C语言概述 C是由丹麦计算机科学家Bjarne Stroustrup于1979年在贝尔实验室开发的一种静态类型、编译式、通用型编程语言。最初被称为"C with Classes"(带类的C),1983年更名为C。它既具有高级语言的抽象特性,又保留了底层硬件操作能力&…

ZED相机与Foxglove集成:加速机器人视觉调试效率的实用方案

随着机器人技术的发展,实时视觉数据流的高效传输和可视化成为提升系统性能的重要因素。通过ZED相机(包括ZED 2i和ZED X)与Foxglove Studio平台的结合,开发者能够轻松访问高质量的2D图像、深度图和点云数据,从而显著提高…

目标检测新纪元:DETR到Mamba实战解析

🚀【实战分享】目标检测的“后 DEⱯ”时代:DETR/DINO/RT-DETR及新型骨干网络探索(含示例代码) 目标检测从 YOLO、Faster R-CNN 到 Transformer 结构的 DETR,再到 DINO、RT-DETR,近两年出现了许多新趋势&am…

【IOS】XCode创建firstapp并运行(成为IOS开发者)

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍XCode创建firstapp并运行 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路…

class类和style内联样式的绑定 + 事件处理 + uniapp创建自定义页面模板

目录 一.class类的绑定 1.静态编写 2.动态编写 二.style内联样式的绑定 三.事件处理 1.案例1 2.案例2 四.uniapp创建自定义页面模板 1.为什么要这么做? 2.步骤 ①打开新建页面的界面 ②在弹出的目录下,新建模板文件 ③用HBuilderX打开该模板…

android 卡顿和丢帧区别

Android 卡顿(Jank)与丢帧(Frame Drop)的核心区别在于问题本质与用户感知,以下是分层解析: ️ 一、本质差异 维度卡顿(Jank)丢帧(Frame Drop)定义用户可感知…

【python实用小脚本-125】基于 Python 的 Gmail 邮件发送工具:实现高效邮件自动化

引言 在现代办公和开发环境中,邮件通信是一种重要的沟通方式。自动化发送邮件可以大大提高工作效率,例如发送通知、报告或文件。本文将介绍一个基于 Python 的 Gmail 邮件发送工具,它能够通过 Gmail 的 SMTP 服务器发送邮件,并支持…

gateway断言配置详解

一、Predicate - 断⾔ 1、简单用法 spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After2017-01-20T17:42:47.789-07:00[America/Denver] 2、自定义断言 新建类VipRoutePredicateFactory,注意VipRoutePredicateFactory名字…

基于大模型的尿毒症全流程预测与诊疗方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 1.3 国内外研究现状 二、尿毒症相关理论基础 2.1 尿毒症的定义、病因与发病机制 2.2 尿毒症的症状与诊断标准 2.3 尿毒症的治疗方法概述 三、大模型技术原理与应用 3.1 大模型的基本概念与发展历程 3.2 大模型…

裸金属服务器租用平台-青蛙云

企业对服务器性能与灵活性的要求与日俱增。青蛙云M-启强裸金属服务器租用平台应运而生,为企业提供了一种兼具物理机性能和云计算弹性的解决方案。裸金属服务器租用平台的优势​(一)高配性能,无虚拟化开销​裸金属服务器直接运行在物理硬件之上&#xff0…

[Terence Tao访谈] AlphaProof系统 | AI嗅觉 | 研究生学习 | 庞加莱猜想(高维) | 复杂问题简单化

玩这些有趣的东西。通常情况下什么也得不到,你必须学会说:“好吧,再试一次,什么都没发生,我会继续前进。” DeepMind的AlphaProof系统 Q:DeepMind的AlphaProof系统是通过强化学习训练的,使用的…

Aseprite工具入门教程4之动画导入Unity

1、时间轴功能 (1)眼睛图标 显示/隐藏图层图层隐藏时无法绘制 (2)锁定图标 锁定后无法移动或编辑图层防止意外在错误图层上绘制 (3)单元格图标 两个点代表帧分开,一个椭圆代表帧统一。分开就…