利用策略模式优化过多if else代码

1.应用场景

现在需要完成这样一项业务,客户在前端输入算法名,后台就调用对应算法来进行模拟实验。假设不使用策略模式,那么我就需要以下代码实现该业务:

    @Autowired
    private DqnAlgorithm dqn;
    @Autowired
    private GreedyAlgorithm greedy;
    @GetMapping("/simu/{alName}")
    public Result getResult(@PathVariable String alName) {
        String ret = null;
        if (alName.equals("DqnAlgorithm")) {
        // 调用dqn的算法
            ret = dqn.compute();
        }else if (alName.equals("DqnAlgorithm")) {
            ret = greedy.compute()
        }
        return ret;
    }

如果我以后实现了更多算法,那么就需要注入更多算法bean,增加更多if else,非常不优雅。
于是决定使用策略模式来解决这个问题。

2.策略模式

利用策略模式优化过多if else代码
首先将算法类抽象出一个接口,接口中有方法compute,实现类都实现这个接口,并且都注册成为Service交给Spring容器管理。因为前端输入算法名alName我们就需要找到正确的实现类Bean并注入,所以需要找出算法接口的所有实现类(AlgorithmServiceLocator提供),根据类名提供其实例(AlgorithmService提供),最终调用方法。
Monodraw第一次画图:

                    ┌──────────────────register────┐
                    │                              │
                    │                              │
           ┌─────────────────┐                     │
           │   IAlgorithm    │                     │
           └───────▲─▲───────┘                     │
                   │ │                             │
          ┌────────┘ └─────────┐                   │
          │                    │                   │
          │                    │                   │
┌──────────────────┐ ┌──────────────────┐          │
│ GreedyAlgorithm  │ │   DqnAlgorithm   │          ▼
└──────────────────┘ └──────────────────┘       .─────.

                                              ,'       .

                   ┌──────map───────────┐    ;           :
                   │                    │    ;           :
                   ▼                    │   ;             :
   ┌───────────────────────────────┐    │   │ Spring Bean │
   │    AlgorithmServiceLocator    │    └───│  container  │
   └───────────────────────────────┘        :             ;
                 get                         :           ;
              IAlgorithm                     :           ;
                   │                          ╲         ╱
                   ▼                           .     ,'
   ┌──────────────────────────────┐              `───'
   │       AlgorithmService       │
   └──────────────────────────────┘

3.文件与代码

接口IAlgorithm

public interface IAlgorithm {
    String compute();
}

两个算法实现类

@Service("DqnAlgorithm")
public class DqnAlgorithm implements IAlgorithm{

    @Override
    public String compute() {
        return "Deep Q learning...";
    }
}
@Service("GreedyAlgorithm")
public class GreedyAlgorithm implements IAlgorithm{
    @Override
    public String compute() {

        return "贪心算法...";
    }
}

获取接口所有实现类的工具类AlgorithmServiceLocator

@Component
public class AlgorithmServiceLocator implements ApplicationContextAware {

    private Map map;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        map = applicationContext.getBeansOfType(IAlgorithm.class);
    }

    public Map getMap() {
        return map;
    }
}

业务类:根据算法名获取对应实现类,并调用方法取得结果

@Service
public class AlgorithmService {

    @Autowired
    private AlgorithmServiceLocator algorithmLocator;

    public IAlgorithm getInstance(String algorithm) {
        IAlgorithm al = null;
        try {
            Map map = algorithmLocator.getMap();
            System.out.println(map);
            al = map.get(algorithm);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return al;
    }

    public String getRet(String algorithm) {
        IAlgorithm al = getInstance(algorithm);
        if (al == null) {
            throw new RuntimeException("无法获取算法!");
        }
        String ret = al.compute();
        return ret;
    }
}

controller

@RestController
public class SimulationController {

    @Autowired
    private AlgorithmService algorithmService;

    @GetMapping("/simu/{alName}")
    public String getResult(@PathVariable String alName) {
        return algorithmService.getRet(alName);
    }
}

测试图1

利用策略模式优化过多if else代码
测试图2
利用策略模式优化过多if else代码
  1. 总结

策略模式需要反射的配合,有时间要学习一下。

参考博客文章

crossoverjie
绝圣弃智-零-csdn

Original: https://www.cnblogs.com/ceeSomething8/p/15973568.html
Author: cee_nil
Title: 利用策略模式优化过多if else代码

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622259/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球