当前位置: 首页 > news >正文

【设计模式深度剖析】【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. 需要动态选择算法的场景:当系统中需要根据不同的条件选择不同的算法进行计算时,策略模式可以提供一个灵活的解决方案。

---

👈️上一篇:职责链模式

设计模式-专栏👈️

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何使用最简单、通俗地理解Python的函数呢?
  • iOS 之homebrew ruby cocoapods 安装
  • 解密Spring Boot:深入理解条件装配与条件注解
  • java+Vue +Spring boot技术开发的UWB高精度定位技术系统源码 uwb定位系统+基站定位
  • ABC351
  • 上心师傅的思路分享(三)--Nacos渗透
  • adb多设备多屏幕调试
  • yarn保姆级安装和使用
  • 实战:部署三台kafka服务集群
  • Linux 内核参数-相关介绍
  • 力扣刷题--728. 自除数【简单】
  • AutoCAD Mechanical机械版专业的计算机辅助设计软件安装包下载安装!
  • 【SQLAlChemy】filter过滤条件如何使用?
  • 定个小目标之刷LeetCode热题(13)
  • 【Linux】rsync远程数据同步工具使用
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • Angular 响应式表单 基础例子
  • es6要点
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • PHP 7 修改了什么呢 -- 2
  • Python连接Oracle
  • ReactNative开发常用的三方模块
  • vue-loader 源码解析系列之 selector
  • 从输入URL到页面加载发生了什么
  • 简单数学运算程序(不定期更新)
  • 思考 CSS 架构
  • 微信开放平台全网发布【失败】的几点排查方法
  • 一道面试题引发的“血案”
  • linux 淘宝开源监控工具tsar
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 大数据全解:定义、价值及挑战
  • ​香农与信息论三大定律
  • #QT(串口助手-界面)
  • #stm32驱动外设模块总结w5500模块
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (C语言)逆序输出字符串
  • (c语言+数据结构链表)项目:贪吃蛇
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)大型网站的系统架构
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .net core Swagger 过滤部分Api
  • .net mvc 获取url中controller和action
  • .Net 应用中使用dot trace进行性能诊断
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • :class的用法及应用
  • @Value获取值和@ConfigurationProperties获取值用法及比较(springboot)
  • @WebServiceClient注解,wsdlLocation 可配置
  • [ C++ ] 类和对象( 下 )
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ 手记 ] 关于tomcat开机启动设置问题
  • [4]CUDA中的向量计算与并行通信模式