​JAVA设计模式(六)——策略模式

article/2025/10/4 15:07:15

下图为所有设计模式,带标记为重点掌握以及工作中常用到的:

在这里插入图片描述
  策略模式是行为型设计模式之一,其作用是让一个类的行为或其算法可以在运行时更改,该模式也算是我比较熟悉的模式之一了,因为之前项目中有幸遇到大佬用过,然后学习了一下,后面会讲述策略模式我在项目中的实战使用场景。

模式名称优点缺点应用场景
策略模式1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好
1、策略类会增多。 2、所有策略类都需要对外暴露。1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题

策略模式Demo

1.创建一个策略接口

public interface Strategy {public int doOperation(int num1, int num2);
}

2.创建多个接口的实现类

// 加法运算
public class OperationAdd implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}
// 减法运算
public class OperationSubtract implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}
// 乘法运算
public class OperationMultiply implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 * num2;}
}

3.创建 Context 类

public class Context {private Strategy strategy;public Context(Strategy strategy){this.strategy = strategy;}public int executeStrategy(int num1, int num2){return strategy.doOperation(num1, num2);}
}

4.测试demo

   public static void main(String[] args) {Context context = new Context(new OperationAdd());    System.out.println("10 + 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationSubtract());      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationMultiply());    System.out.println("10 * 5 = " + context.executeStrategy(10, 5));}

测试结果如下:
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50

  根据以上的demo案例我们可以看出来,策略模式的核心思想其实就是不同的行为会获取对应行为的类对象,从而获取该行为对应的结果。策略模式通常被用于进行解决在有多种算法相似的情况下,使用 if…else 所带来的复杂性和难以维护的问题。

策略模式实际案例一

1.使用背景

  项目中开发工单模块时,遇到工单结单,此时结单的方式有多种,包括:现金支付、微信支付、支付宝支付、账户余额支付等等,并且各种结单方式也有不同的逻辑。此时我们应该如何书写结单接口呢,难道是根据结单类型去进行if else的判断书写吗?虽然这种方式最后也可以实现功能,但是代码维护起来就比较费劲了,而且也不便于以后的扩展,因此我们完全可以采用策略模式进行解决。以上代码为我们项目代码,不可以直接使用,大家可以参考。

2.示例代码

1.创建策略接口

public interface AppEndWorkOrderService {/*** APP-维修工单-结单** @param id 工单ID* @param order 订单信息* @param callbackAddress 回调地址* @return 成功/失败标志* @date 2021/10/12 9:35*/R<Map<String, Object>> endWorkOrder(Long id, Order order, String callbackAddress);
}

2.创建接口的实现类(现金支付、支付宝支付)

/*** 现金支付结单服务** @author wyj* @date 2021/10/12 9:38*/
@Log4j2
@Service("appCashPayEndWorkOrderService")
public class AppCashPayEndWorkOrderServiceImpl implements AppEndWorkOrderService {@Autowired private AppOrderRepairRecordService appOrderRepairRecordService;@Autowired private ChargeCreateBizApi chargeCreateBizApi;// 策略服务注册static {StrategyContext.registerProvider(StrategyContext.PAY_TYPE + OrderPayTypeEnum.CASH_PAY.getValue(),AppCashPayEndWorkOrderServiceImpl.class);}@Overridepublic R<Map<String, Object>> endWorkOrder(Long id, Order order , String callbackAddress) {appOrderRepairRecordService.paySuccess(id, null, null);// 生成缴费记录ChargeCreateRequestDTO requestDTO = new ChargeCreateRequestDTO();requestDTO.setBusinessNo(id);requestDTO.setChargeChannel(ChargeChannelEnum.WX_MS);requestDTO.setChargePayMethod(ChargePayMethodEnum.CASH);chargeCreateBizApi.createByScene(requestDTO);return R.success(null);}
}
/*** 支付宝结单服务** @author wyj* @date 2021/10/12 9:38*/
@Log4j2
@Service("appAlipayPayEndWorkOrderServiceImpl")
public class AppAlipayPayEndWorkOrderServiceImpl implements AppEndWorkOrderService {// 策略服务注册static {StrategyContext.registerProvider(StrategyContext.PAY_TYPE + OrderPayTypeEnum.ALIPAY_PAY.getValue(),AppAlipayPayEndWorkOrderServiceImpl.class);}@Overridepublic R<Map<String, Object>> endWorkOrder(Long id, Order order, String callbackAddress) {// 支付宝支付后进行工单结单\订单结束等操作return null;}
}

3.创建工具类StrategyContext

@Component
public class StrategyContext {// keypublic static final String PAY_TYPE = "pay-type-";// 策略映射mapprivate static final Map<String, Class<?>> providers = new HashMap<>();// 提供给策略具体实现类的注册返回public static void registerProvider(String subjectId, Class<?> provider) {providers.put(subjectId, provider);}// 返回策略映射的具体服务public static Object getService(String subjectId) {Class<?> providerClazz = providers.get(subjectId);return SpringContextHelper.getBean(providerClazz);}}

4.创建工具类

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class SpringContextHelper implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextHelper.applicationContext = applicationContext;}public static Object getBean(Class<?> clazz) throws BeansException {return  applicationContext.getBean(clazz);}public static Object getBean(String name) throws BeansException {return applicationContext.getBean(name);}}

4.策略使用
在这里插入图片描述

策略模式实际案例二

1.使用背景

项目中进行指令数据打包时,根据不同的编号去选择不同的实现类去完成数据打包,此处也选择使用策略模式完成,但是实现方式和第一个稍微有些区别。大家可以参考一下;

2.示例代码

1.创建一个待实现的接口

public interface DataPack {String packClickCmd(String cmdCode);
}

2.分别创建2个不同的实现类DataPackHandler和NewFlowMeterDataPackHandler

import org.springframework.stereotype.Service;@Service(DataPackHandlerContext.POLICY_PREFIX + 100)
public class DataPackHandler implements DataPack {public String packClickCmd(String cmdCode) {cmdCode = "DataPackHandler:" + cmdCode;System.out.println(cmdCode);return cmdCode;}
}
import org.springframework.stereotype.Service;@Service(DataPackHandlerContext.POLICY_PREFIX + 101)
public class NewFlowMeterDataPackHandler implements DataPack {public String packClickCmd(String cmdCode) {cmdCode = "NewFlowMeterDataPackHandler:" + cmdCode;System.out.println(cmdCode);return cmdCode;}
}

3.创建一个策略模式的工具类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 指令打包策略工具类** @date 2022/7/22 10:37*/
@Component
public class DataPackHandlerContext {@Autowiredprivate Map<String, DataPack> dataPackMap = new ConcurrentHashMap<>();public static final String POLICY_PREFIX = "pack";/*** 根据协议数据解析对应实例** @param protocolVersion* @return*/public DataPack getDataPack(String protocolVersion) {return dataPackMap.get(POLICY_PREFIX + protocolVersion);}
}

4.使用策略模式

import com.weiyiji.exception.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@Autowiredprivate DataPackHandlerContext dataPackHandlerContext;@GetMapping("/getName")public R<String> getName(String version) {DataPack dataPack = dataPackHandlerContext.getDataPack(version);String test = dataPack.packClickCmd("test");return R.success(test);}
}

5.结果展示
在这里插入图片描述

在这里插入图片描述

小结

  本实例中就是在同一个接口中根据不同的支付方式获取对应支付方式对应的实体类对象,然后进行其后续操作。


http://chatgpt.dhexx.cn/article/B2PNHihx.shtml

相关文章

java 策略模式例子_策略模式—Java实现(转)

1. 现实需求 客户有了新的需求&#xff0c;这时我们直接新增策略即可&#xff0c;改很少的代码。基本符合我们面向对象原则中的开闭原则(对扩展开放&#xff0c;对修改关系)&#xff0c;实现了高内聚低耦合。 2. 策略模式定义 策略模式&#xff0c;又叫算法簇模式&#xff0c;就…

Java设计模式(五)策略模式-在SpringBoot项目中的实际应用

文章目录 什么是策略模式优点缺点使用场景结构图 策略模式的简单示例策略模式的项目实战场景实现 小结 什么是策略模式 官话&#xff1a;策略模式(Strategy Pattern)&#xff1a; 定义一系列算法类&#xff0c;将每一个算法封装起来&#xff0c;并让它们可以相互替换&#xff…

java调用微信加密_java微信消息加解密

今天心血来潮就信手拈来学了下微信消息加解密的知识,忽然觉得微信真的好强大。可能在大部分项目微信消息的加解密都用不上,但是仍然不排除有使用到的情况,如涉及金钱方面的微信应用包括商城类、金融类还有其他安全级别要求很高的微信应用。针对这些情况我觉得还是有必要分享…

spring如何使用策略模式

这里使用登录做例子介绍如何实现登录的多种策略 上图是策略模式的基础模型。 context Context上下文角色&#xff0c;也叫Context封装角色&#xff0c;起承上启下的作用&#xff0c;屏蔽高层模块对策略、算法的直接访问&#xff0c;封装可能存在的变化。 Strategy 策略角色…

java设计模式实战-(反射+策略模式)

学完23种设计模式&#xff0c;相信很多同学都疑问&#xff0c;除了单例模式、工厂模式其他模式还有运用的场景吗&#xff1f; 现在这里就举一个例子。 首先策略模式需要先有了解&#xff0c;我们常用策略模式解决实际开发中的if else特别多的场景。但是在实际的开发中&#x…

Java23种设计模式之策略模式【普通写法以及spring中的写法】

目录 设计模式简介策略模式的简介普通写法案例基于注解式改造的案例优缺点策略模式的使用场景 设计模式简介 将设计者的思维融入大家的学习和工作中&#xff0c;更高层次的思考&#xff01; • 创建型模式&#xff1a; – 单例模式、工厂模式、抽象工厂模式、建造者模式、原型…

Java设计模式-策略模式(支付业务的优化)

一、什么情况下使用策略模式 功能类似的业务功能&#xff0c;避免创建多个接口&#xff0c;大量if else 判断逻辑&#xff0c;简化代码 二、我以支付为例&#xff08;支付方式有微信&#xff0c;支付宝支付&#xff09; 1、新建策略抽象类或者接口 public interface ThirdP…

java策略模式实战示例

现已放在gitee上,可以不下载直接参考一下即: https://gitee.com/zhang-xiao-xiang/zxx-pattern 日常碰到的业务概述 登录类型,支付类型,供应商渠道,不同等级会员享受的优惠券价格不一样,等等业务判断,大量if else导致拓展(侧重新增)极其困难,维护(侧重修改)自然是改起来头痛(…

【JAVA设计模式】策略模式

1.什么是策略模式&#xff1f; 策略模式是对算法的包装&#xff0c;是把使用算法的责任和算法本身分割开来&#xff0c;委派给不同的对象管理&#xff0c;相同的事情-----选择不用同方式 &#xff08;不同实现&#xff09;举例子&#xff0c;最终可以实现解决多重if判断问题。 …

java微信关注事件_java策略模式在接收微信事件推送上的具体应用

java策略模式&#xff0c;在我的认知中是根据不同选择执行不同的实现。通过if或者switch-case也能实现这种逻辑&#xff0c;但是代码冗余&#xff0c;可扩展性不强。 百度百科上的解释为策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景…

Java设计模式之3种策略模式实现

一、什么是策略模式 所谓策略模式&#xff0c;就是定义了一组策略&#xff0c;分别封装在不同类中&#xff0c;每种策略都可以根据当前场景相互替换&#xff0c;从而使策略的变化可以独立于操作者。比如我们要去某个地方&#xff0c;会根据距离的不同来选择不同的出行方式&…

java8 策略模式_JAVA设计模式之策略模式

策略模式&#xff1a;在策略模式(Strategy Pattern)中&#xff0c;一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式中&#xff0c;我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对…

git如何提交代码

代码提交 代码提交一般有五个步骤&#xff1a; 1.查看目前代码的修改状态 2.查看代码修改内容 3.暂存需要提交的文件 4.提交已暂存的文件 5.同步到服务器 1. 查看目前代码的修改状态 提交代码之前&#xff0c;首先应该检查目前所做的修改&#xff0c;运行git status命令 a)…

修改git提交时间

问题描述&#xff1a; 修改git提交记录的时间 git脚本&#xff1a; 此方法使用github上的开源工具完成。感谢无私的奉献者&#xff01; 操作步骤&#xff1a; github上下载文件 解压文件夹&#xff0c;把git-redate文件置于git安装目录的\mingw64\libexec\git-core文件夹…

git提交时常用命令

git提交时常用命令 一、git命令 -- 本地仓库与远程仓库建立链接 git init &#xff08;初始化本地仓库&#xff09; git remote add origin 远程仓库网址 git remote -v (查看远程仓库) git remote rm origin (删除远程分支)-- checkout多种用法 git checkout 文件名 &#…

git提交分支

1. git提交分支相关 在本地新建分支&#xff0c;保证和远程分支一样 git checkout -b 分支名如果分支已存在&#xff0c;只需要切换的话 git checkout 分支名提交前先把代码拉下来更新一下&#xff0c;确保不会覆盖别人的代码 git pull origin 远程分支(如果有)解决冲突 git …

Git 的提交

1 提交对象 理解Git分支&#xff0c;就需要了解提交及在提交过程中产生的提交对象&#xff08;commit object&#xff09;。在进行提交时Git会存储一个提交对象&#xff0c;其中包含一个指针&#xff0c;它指向此次提交时暂存内容的快照。除此之外&#xff0c;提交对象中还包含…

git代码提交

代码提交 代码提交一般有五个步骤&#xff1a; 1.查看目前代码的修改状态 2.查看代码修改内容 3.暂存需要提交的文件 4.提交已暂存的文件 5.同步到服务器 1. 查看目前代码的修改状态 提交代码之前&#xff0c;首先应该检查目前所做的修改&#xff0c;运行git status命令 a…

【git提交】流程

1- git提交&#xff08;分支合并&#xff09;操作流程&#xff1a; git 提交代码到自己的分支&#xff0c;并合并到主分支的完整流程 分支 sml &#xff0c; 主分支&#xff0c; master 分支msl上操作 git status git add . git commit -m ‘xxxxxx’ git pull origin master…

git提交规范,规范自己的提交标准

为了规范我的git提交内容&#xff0c;提交的时候commit -m “备注的信息”&#xff0c;但是每个人的备注信息千奇百怪&#xff0c;为了统一&#xff0c;我们进行了git的规范。 首先要全局安装commitizen npm i -g commitizen4.2.4然后安装插件 npm i cz-customizable6.3.0…