• 设计模式之策略模式【内附通过工厂方法+枚举实现根据参数调用不同的策略】


           最近遇到挺多根据不同入参调用不同处理方法的场景,故引起思考,能不能别这么多if else,能不能别每次添加一种实现就去加一个if,能不能看起来高大上一点点...;虽然脑子经常提示自己要多用设计模式,但由于遇到的公司都是赶着上线堆功能,所以一直很少使用,但这次我实在忍不住了,加个班来重构了部分代码..;废话不多说,咱开干吧!

    一、个人理解与实现

    策略模式,故名思意,就是我有多种策略,根据不同情况去使用不同策略;

    具体代码实现分为5部分:

    1.抽象策略:就是定义所有策略共同的方法,定义一个策略公共接口;

    2.实现策略:就是实现抽象策略的方法,实现策略公共接口的具体实现类;

    因为要根据入参来判断调用具体的实现策略,所以还需一个枚举类来建立参数值与实现类的对应关系;对应关系有了,还需一个通过反射来实例化具体策略实现类对象的工厂类,因此多加2步:

    3.枚举类建立参数与具体策略实现类的对应关系:就是定义一个枚举类,设置对应关系,并实现一个方法通过入参来获取对应的实现类的path(用以反射生成对象);

    4.反射实例化对象工厂:就是通过path反射生成不同的实现类;

    5.上下文环境(调用入口);统一了调用入口,调用工厂类统一的方法,入参调用不同策略;

    二、实现场景

    实现场景:拿最近的一个场景来模拟吧,我要对多种不同题目进行评分,根据传过来的题目类型,调用不同的评分方法(策略);

    三、具体实现

    根据第一点的个人理解来操作实现:

    1.定义一个抽象策略接口:

    1. package com.zcouyang.demo;
    2. /**
    3. * 题型评分策略
    4. */
    5. public interface ScoreStrategy {
    6. /**
    7. * 共同的评分行为方法
    8. * @return
    9. */
    10. double toStart(String test);
    11. }

    2.具体的实现策略类

    2.1单选题算分策略:

    1. package com.zcouyang.demo;
    2. /**
    3. * 单选题算分规则
    4. *
    5. *
    6. * 对单选题进行算分
    7. *
  • *
  • * @author zcouyang
  • */
  • public class ChoiceStrategy implements ScoreStrategy {
  • /**
  • *
  • * 规则算分入口
  • * 对单选题进行算分
  • *
  • * @param test
  • */
  • @Override
  • public double toStart(String test) {
  • System.out.println("进来了单选题算分策略:"+test);
  • return 0d;
  • }
  • }
  • 2.2多选题算分策略:

    1. package com.zcouyang.demo;
    2. /**
    3. * 多选题算分规则
    4. *
    5. *
    6. * 对多选题进行算分
    7. *
  • *
  • * @author zcouyang
  • */
  • public class MultiChoiceStrategy implements ScoreStrategy {
  • /**
  • *
  • * 规则算分入口
  • * 对多选题进行算分
  • *
  • * @param test
  • */
  • @Override
  • public double toStart(String test) {
  • System.out.println("进来了多选题算分策略:"+test);
  • return 0;
  • }
  • }
  • 3.枚举类建立参数与具体策略实现类的对应关系

    1. package com.zcouyang.demo;
    2. import cn.hutool.core.util.StrUtil;
    3. /**
    4. * 评分策略枚举
    5. * @author zcouyang
    6. * @date 2022/9/06 15:45
    7. */
    8. public enum ScoreEnumStrategy {
    9. /**
    10. * 单选题评分
    11. */
    12. CHOICE_SCORE("choice","com.zcouyang.demo.ChoiceStrategy"),
    13. /**
    14. * 多选题评分
    15. */
    16. MULTICHOICE_SCORE("multiChoice","com.zcouyang.demo.MultiChoiceStrategy");
    17. private String type;
    18. private String className;
    19. ScoreEnumStrategy() {
    20. }
    21. ScoreEnumStrategy(String type, String className) {
    22. this.type = type;
    23. this.className = className;
    24. }
    25. public static String getClassNameByType(String type) {
    26. String className = "";
    27. if (StrUtil.isBlank(type)) {
    28. return className;
    29. }
    30. for (ScoreEnumStrategy e : ScoreEnumStrategy.values()) {
    31. if (e.type.equalsIgnoreCase(type)) {
    32. className = e.className;
    33. break;
    34. }
    35. }
    36. return className;
    37. }
    38. public String getType() {
    39. return type;
    40. }
    41. public String getClassName() {
    42. return className;
    43. }
    44. }

    4.反射实例化对象工厂

    1. package com.zcouyang.demo;
    2. /**
    3. * 策略工厂反射执行
    4. * @author zcouyang
    5. * @date 2022/9/06 15:45
    6. */
    7. public class StrategyFactory {
    8. /**
    9. * 使用策略工厂获取具体策略实现
    10. * @param type
    11. * @return
    12. */
    13. public static ScoreStrategy getScoreStrategy(String type) {
    14. try {
    15. return (ScoreStrategy) Class.forName(ScoreEnumStrategy.getClassNameByType(type)).newInstance();
    16. } catch (InstantiationException e) {
    17. e.printStackTrace();
    18. } catch (IllegalAccessException e) {
    19. e.printStackTrace();
    20. } catch (ClassNotFoundException e) {
    21. e.printStackTrace();
    22. }
    23. return null;
    24. }
    25. }

    5.上下文环境(调用入口)

    1. package com.zcouyang.demo;
    2. import cn.hutool.core.util.StrUtil;
    3. /**
    4. * 评分策略上下文
    5. *
    6. * @author zcouyang
    7. * @date 2022/9/06 15:41
    8. */
    9. public class ScoreContextStrategy {
    10. /**
    11. * 获取具体的策略实现
    12. *
    13. * @param test
    14. * @return
    15. */
    16. public static double toScore(String test) {
    17. ScoreStrategy scoreStrategy = StrategyFactory.getScoreStrategy(test);
    18. return scoreStrategy.toStart(test);
    19. }
    20. }

    三、运行测试

    1.测试类

    1. package com.zcouyang.demo;
    2. public class Test {
    3. public static void main(String[] args) {
    4. //单选题策略
    5. ScoreContextStrategy.toScore("choice");
    6. //多选题策略
    7. ScoreContextStrategy.toScore("multiChoice");
    8. }
    9. }

    2.结果输出

     

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

    参考:Java 设计模式--策略模式,枚举+工厂方法实现 - satire - 博客园

  • 相关阅读:
    爬虫小案例爬取塔某小说内容
    web前端日常更新 8.16
    全职RISC-V芯片D1开发板使用adb串口COM连接设备和文件上传下载
    某银行软件测试笔试题,满分一百你能得多少分?
    图文验证码怎么测试及自动化测试怎么解决验证码问题?
    Flutter:多线程Isolate的简单使用
    云原生周刊:Argo CD v2.12 发布候选版本 | 2024.06.24
    如何快速实现直播美颜功能 - 接入美颜SDK详解
    Linux利用源码包升级Nginx到1.23.1用以解决nginx安全漏洞问题
    Map接口
  • 原文地址:https://blog.csdn.net/Ouyzc/article/details/126753488