【设计模式深度剖析】【4】【行为型】【策略模式】

👈️上一篇:职责链模式

设计模式-专栏👈️

---

文章目录

  • 策略模式
  • 定义
    • 英文原话
    • 直译
  • 角色
    • 类图
    • 策略接口`Strategy`:
    • 具体策略类
    • 上下文类Context
    • 测试类
  • 策略模式的应用
    • 策略模式的优点
    • 策略模式的缺点
    • 策略模式的使用场景

策略模式

策略模式(Strategy Pattern)

Strategy策略也称作Policy政策。

想象一下我们正在玩一个角色扮演游戏。在游戏中,我们的角色有多种技能可以选择,比如“火球术”、“冰霜箭”和“治愈术”。每种技能都有不同的效果和用途。现在,游戏设计师希望让我们能够随时切换这些技能以适应不同的战斗场景。

策略模式就是这样一种设计思想。它允许我们定义不同的“技能”(即策略),然后在游戏中根据需要随时切换使用哪种技能。这样,我们就可以更加灵活地应对各种战斗情况了。

同样地,在计费系统或商城促销活动中,策略模式也允许我们根据不同的条件选择不同的计费方式或优惠策略,使得系统更加灵活和可配置。

定义

英文原话

Define a family of algorithms, encapsulate each one, and make them interchangeable.

直译

定义一系列的算法,把它们一个个封装起来,并且是他们可相互替换(必然实现了相同的接口,不然无法相互替换,该接口就是策略接口)

本模式使得算法可独立于使用它的客户而变化。

角色

  1. 策略接口(Strategy):定义所有支持的算法的公共接口。
  2. 具体策略(ConcreteStrategy):实现策略接口的类,具体策略类实现了算法的具体逻辑。
  3. 上下文(Context):使用策略接口的类,也称为“上下文”或“客户端”。上下文类内部持有一个策略对象的引用,并且负责在需要的时候调用策略对象的算法。

类图

在这里插入图片描述

在策略模式中,我们可以将这三个角色用Java类来具体实现。以下是一个简化的策略模式示例,其中包含了Strategy(策略接口)、ConcreteStrategy(具体策略类)和Context(上下文类)的实现。

策略接口Strategy

// Strategy.java  
public interface Strategy {  void executeStrategy();  
}

具体策略类

这里假设有两个具体策略类ConcreteStrategyAConcreteStrategyB

// ConcreteStrategyA.java  
public class ConcreteStrategyA implements Strategy {  @Override  public void executeStrategy() {  System.out.println("执行策略A");  // 策略A的具体实现  }  
}  // ConcreteStrategyB.java  
public class ConcreteStrategyB implements Strategy {  @Override  public void executeStrategy() {  System.out.println("执行策略B");  // 策略B的具体实现  }  
}

上下文类Context

它持有一个策略对象的引用,并提供了设置策略和执行策略的方法:

// Context.java  
public class Context {  private Strategy strategy;  // 构造函数  public Context(Strategy strategy) {  this.strategy = strategy;  }  // 设置策略  public void setStrategy(Strategy strategy) {  this.strategy = strategy;  }  // 执行策略  public void executeStrategy() {  strategy.executeStrategy();  }  
}

测试类

现在,我们可以编写一个示例来展示如何使用策略模式:

// StrategyPatternDemo.java  
public class StrategyPatternDemo {  public static void main(String[] args) {  // 创建策略对象  Strategy strategyA = new ConcreteStrategyA();  Strategy strategyB = new ConcreteStrategyB();  // 创建上下文对象并设置策略  Context context = new Context(strategyA);  context.executeStrategy(); // 输出:执行策略A  // 修改策略  context.setStrategy(strategyB);  context.executeStrategy(); // 输出:执行策略B  }  
}/* Output:
执行策略A
执行策略B
*///~

在这个示例中,Context类可以根据需要改变其内部持有的Strategy对象,从而改变其行为。

这是策略模式的核心思想:将算法的使用与算法的实现分离开来,使得算法可以独立于使用它的客户端变化。

策略模式的应用

策略模式是一种行为型设计模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。在软件系统中,策略模式使得算法可以独立于使用它的客户端变化。

策略模式的优点

  1. 算法自由切换:由于策略类实现了同一个接口,因此它们之间可以自由切换,这使得系统更加灵活和可维护。
  2. 易于扩展:当需要增加新的算法时,只需要实现该接口即可,符合开闭原则。
  3. 避免使用多重条件语句:使用策略模式可以避免在代码中出现大量的if-else语句,使代码更加清晰、简洁和易于维护。
  4. 提高算法的保密性和安全性:客户端只需要知道它使用了哪些算法,而不需要知道这些算法的具体实现细节,这有助于保护算法的安全性和保密性。

策略模式的缺点

  1. 客户端必须知道所有的策略类:客户端需要了解并决定使用哪一个策略类,这可能会增加客户端的复杂性。
  2. 可能造成策略类过多:当系统中存在大量的策略时,可能会导致策略类过多,增加了系统的复杂性。

策略模式的使用场景

  1. 计费系统:对于不同用户类型和消费金额采用不同的计费方式,可以使用策略模式来定义不同的计费策略。
  2. 游戏开发中的角色技能系统:不同角色拥有不同的技能,可以根据角色的选择使用不同的技能策略进行攻击或防御。
  3. 商城促销活动:根据不同的促销活动采取不同的优惠方式,如打折、满减等,策略模式可以方便地管理和切换这些优惠策略。
  4. 需要动态选择算法的场景:当系统中需要根据不同的条件选择不同的算法进行计算时,策略模式可以提供一个灵活的解决方案。

---

👈️上一篇:职责链模式

设计模式-专栏👈️

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

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

相关文章

Java--递归

1.递归就是A方法调用A方法,也就是调用自己本身 2.利用递归可以用简单的程序来解决一些复杂的问题,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复…

Ubuntu 24.04 LTS 安装配置 MySQL Community Server 8.4.0 LTS

1 安装 Apt Repository ​​​​​​​地址MySQL :: Download MySQL APT Repository sudo dpkg -i mysql-apt-config_0.8.30-1_all.deb #安装mysql 8.4 lts sudo apt update sudo apt-get install mysql-server #修改mysql root密码策略 2 查看版本 testtest:~$ mysqld --v…

力扣每日一题 6/10

881.救生艇[中等] 题目: 给定数组 people 。people[i]表示第 i 个人的体重 ,船的数量不限,每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。 返回 承载所有人所需的最小船…

LinkedList详解(含数据结构动画演示)

目录 LinkedList详解1、LinkedList的继承体系2、LinkedList的构造函数3、LinkedList的add(E e)方法4、LinkedList的Node节点5、双向链表的概念和Node节点的详细解释6、LinkedList的add(E e)方法梳理7、LinkedList的getXXX方法8、LinkedList的removeXXX方法①、removeFirst()方法…

Tomcat源码解析(八):一个请求的执行流程(附Tomcat整体总结)

Tomcat源码系列文章 Tomcat源码解析(一):Tomcat整体架构 Tomcat源码解析(二):Bootstrap和Catalina Tomcat源码解析(三):LifeCycle生命周期管理 Tomcat源码解析(四):StandardServer和StandardService Tomcat源码解析(五)&…

吴恩达神经网络学习笔记1

代码解释 并不是全部代码,思路的流程 import numpy as np# 如何判断咖啡豆是烤好了 # 假设此神经网络由2层构成###### 这部分代码只是如何建立2层网络, ###### 并不包含如何加载神经网络中的参数 w 和 b######################## 第1层网络# x 是…

Ruoyi5.x RuoYi-Vue-Plus新建Translation翻译类

若依框架(RuoYi)中的Translation翻译类主要作用在于实现字段值的转换或翻译功能,以提高数据展示的准确性和友好性。以下是其具体作用的一些关键点: 字段值转换:若依框架在处理数据时,有时需要将某些字段的…

CrawlSpace爬虫部署框架介绍

CrawlSpace爬虫部署框架介绍 全新的爬虫部署框架,为了适应工作的爬虫部署的使用,需要自己开发一个在线编写爬虫及部署爬虫的框架,框架采用的是Django2.2bootstap依赖scrapyd开发的全新通用爬虫在线编辑部署及scrapy项目的部署框架。项目实现的…

读AI未来进行式笔记08自主57

1. 自主57 1.1. 自主57被视为继火药、核57之后的“第三次zhan筝革命” 1.2. 虽然地雷和导弹揭开了早期简单自主57的序幕,但运用了AI技术的真正的自主57才是正片 1.2.1. AI自主57让整个sha戮过程:搜寻目标、进入zhan斗、抹sha生命,完全无须…

【Labview】通过串口通信从上位机读取和写入数据

最近博主需要通过Labview的上位机控制一个温控仪表,主要实现在上位机读取实时温度和设定的目标温度,以及通过上位机设定目标温度。这里将其中遇到的问题和心得分享给大家,博主自己也做一个记录。 由于温控仪表采用的485通讯,modb…

C语言——字符数组

一、字符数组的定义 语言字符数组的定义是指在C语言中可以使用一组连续的字符来存储和处理字符串。在定义字符数组时,需要指定数组的大小,并且可以初始化数组的内容。 1、字符数组方式: char str[] "Hello,world!";2、指针方式…

目标检测数据集 - 垃圾桶满溢检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍:垃圾桶满溢检测数据集,真实场景高质量图片数据,涉及场景丰富,比如城市道边垃圾桶满溢、小区垃圾桶满溢、社区垃圾桶满溢、农村道边垃圾桶满溢、垃圾集中处理点垃圾桶满溢、公园垃圾桶满溢数据等。数据集标注标签划分为…

c++ 里函数选择的优先级:普通函数、模板函数、万能引用,函数重载的常量左值引用、右值引用,编译器选择哪个执行呢?

看大师写的代码时,除了在类里定义了 copy 构造函数,移动构造函数,还定义了对形参采取万能引用的构造函数,因此有个疑问,这时候的构造函数优先级是什么样的呢?简化逻辑测试一下,如下图&#xff0…

【Vue】项目创建目录初始化

文章目录 vue-cli 建项目调整初始化目录结构 vue-cli 建项目 1.安装脚手架 (已安装) npm i vue/cli -g2.创建项目 vue create hm-shopping选项 Vue CLI v5.0.8 ? Please pick a preset:Default ([Vue 3] babel, eslint)Default ([Vue 2] babel, eslint) > Manually sel…

new RegExp(Reg).test(value)无效

目录 前沿 问题分析 eval 函数 # 定义和用法 # 语法 # 浏览器支持 # 实例 使用eval函数 优化 拓展 —— 要么旅行,要么读书,身体和灵魂必须有一个在路上。 前沿 之前写过一篇正则表达式的基础:http://t.csdnimg.cn/45Da3 今天继…

张霖浩在娱乐“名利场”玩出“修罗场”的贵族范儿

众所周知娱乐圈是个大型“名利场”!近日,2025年北京广播电视台春晚发布会现场,众大咖汇聚,妆容、装扮、穿搭,更是争奇斗艳、八仙过海各显神通。同时,也揭露出娱乐圈当下穿搭界”修罗场”的残酷现实。在出彩…

AI智能体的分级

技术的分级 人们往往通过对一个复杂的技术进行分级,明确性能、适用范围和价值,方便比较、选择和管理,提高使用效率,促进资源合理分配和技术改进和标准化。 比如,国际汽车工程师学会(SAE)定义了自…

2024年第三届数据统计与分析竞赛(B题)数学建模完整思路+完整代码全解全析

你是否在寻找数学建模比赛的突破点?数学建模进阶思路! 详细请查 作为经验丰富的数学建模团队,我们将为你带来2024年第三届数据统计与分析竞赛(B题)的全面解析。这个解决方案包不仅包括完整的代码实现,还有…

排序题+贪心

排序力扣题 一&#xff1a;合并区间 56. 合并区间 方法一&#xff1a;先排序再合并 如图&#xff0c;把区间按照起点从小到达排序&#xff0c;如果起点相同那么按照终点小的优先排序 然后每次记录一个区间&#xff0c;访问下一个区间&#xff1a; 如果下一个区间的起点<前…

Vue TypeScript 实战:掌握静态类型编程

title: Vue TypeScript 实战&#xff1a;掌握静态类型编程 date: 2024/6/10 updated: 2024/6/10 excerpt: 这篇文章介绍了如何在TypeScript环境下为Vue.js应用搭建项目结构&#xff0c;包括初始化配置、创建Vue组件、实现状态管理利用Vuex、配置路由以及性能优化的方法&#x…