最近遇到挺多根据不同入参调用不同处理方法的场景,故引起思考,能不能别这么多if else,能不能别每次添加一种实现就去加一个if,能不能看起来高大上一点点...;虽然脑子经常提示自己要多用设计模式,但由于遇到的公司都是赶着上线堆功能,所以一直很少使用,但这次我实在忍不住了,加个班来重构了部分代码..;废话不多说,咱开干吧!
策略模式,故名思意,就是我有多种策略,根据不同情况去使用不同策略;
具体代码实现分为5部分:
1.抽象策略:就是定义所有策略共同的方法,定义一个策略公共接口;
2.实现策略:就是实现抽象策略的方法,实现策略公共接口的具体实现类;
因为要根据入参来判断调用具体的实现策略,所以还需一个枚举类来建立参数值与实现类的对应关系;对应关系有了,还需一个通过反射来实例化具体策略实现类对象的工厂类,因此多加2步:
3.枚举类建立参数与具体策略实现类的对应关系:就是定义一个枚举类,设置对应关系,并实现一个方法通过入参来获取对应的实现类的path(用以反射生成对象);
4.反射实例化对象工厂:就是通过path反射生成不同的实现类;
5.上下文环境(调用入口);统一了调用入口,调用工厂类统一的方法,入参调用不同策略;
实现场景:拿最近的一个场景来模拟吧,我要对多种不同题目进行评分,根据传过来的题目类型,调用不同的评分方法(策略);
根据第一点的个人理解来操作实现:
- package com.zcouyang.demo;
-
-
- /**
- * 题型评分策略
- */
- public interface ScoreStrategy {
-
- /**
- * 共同的评分行为方法
- * @return
- */
- double toStart(String test);
- }
2.1单选题算分策略:
- package com.zcouyang.demo;
-
-
-
- /**
- * 单选题算分规则
- *
- *
- * 对单选题进行算分
- *
- *
- * @author zcouyang
- */
- public class ChoiceStrategy implements ScoreStrategy {
-
- /**
- *
- * 规则算分入口
- * 对单选题进行算分
- *
- * @param test
- */
- @Override
- public double toStart(String test) {
- System.out.println("进来了单选题算分策略:"+test);
- return 0d;
- }
- }
2.2多选题算分策略:
- package com.zcouyang.demo;
-
-
- /**
- * 多选题算分规则
- *
- *
- * 对多选题进行算分
- *
- *
- * @author zcouyang
- */
- public class MultiChoiceStrategy implements ScoreStrategy {
-
- /**
- *
- * 规则算分入口
- * 对多选题进行算分
- *
- * @param test
- */
- @Override
- public double toStart(String test) {
- System.out.println("进来了多选题算分策略:"+test);
- return 0;
- }
- }
- package com.zcouyang.demo;
-
- import cn.hutool.core.util.StrUtil;
-
- /**
- * 评分策略枚举
- * @author zcouyang
- * @date 2022/9/06 15:45
- */
- public enum ScoreEnumStrategy {
-
- /**
- * 单选题评分
- */
- CHOICE_SCORE("choice","com.zcouyang.demo.ChoiceStrategy"),
-
- /**
- * 多选题评分
- */
- MULTICHOICE_SCORE("multiChoice","com.zcouyang.demo.MultiChoiceStrategy");
-
-
- private String type;
- private String className;
-
- ScoreEnumStrategy() {
- }
-
- ScoreEnumStrategy(String type, String className) {
- this.type = type;
- this.className = className;
- }
-
- public static String getClassNameByType(String type) {
- String className = "";
- if (StrUtil.isBlank(type)) {
- return className;
- }
-
- for (ScoreEnumStrategy e : ScoreEnumStrategy.values()) {
- if (e.type.equalsIgnoreCase(type)) {
- className = e.className;
- break;
- }
- }
- return className;
- }
-
- public String getType() {
- return type;
- }
-
- public String getClassName() {
- return className;
- }
- }
- package com.zcouyang.demo;
-
- /**
- * 策略工厂反射执行
- * @author zcouyang
- * @date 2022/9/06 15:45
- */
- public class StrategyFactory {
-
- /**
- * 使用策略工厂获取具体策略实现
- * @param type
- * @return
- */
- public static ScoreStrategy getScoreStrategy(String type) {
- try {
- return (ScoreStrategy) Class.forName(ScoreEnumStrategy.getClassNameByType(type)).newInstance();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
- package com.zcouyang.demo;
-
- import cn.hutool.core.util.StrUtil;
-
- /**
- * 评分策略上下文
- *
- * @author zcouyang
- * @date 2022/9/06 15:41
- */
- public class ScoreContextStrategy {
-
- /**
- * 获取具体的策略实现
- *
- * @param test
- * @return
- */
- public static double toScore(String test) {
- ScoreStrategy scoreStrategy = StrategyFactory.getScoreStrategy(test);
- return scoreStrategy.toStart(test);
- }
- }
1.测试类
- package com.zcouyang.demo;
-
- public class Test {
-
-
- public static void main(String[] args) {
-
- //单选题策略
- ScoreContextStrategy.toScore("choice");
-
- //多选题策略
- ScoreContextStrategy.toScore("multiChoice");
- }
- }
2.结果输出

至此已经完成测试,大伙可根据业务需求进行改造使用,如有错漏,请指正!