最近完成了我们公司的公众号开发,在微信消息路由选择的时候一开始都是用if-else 来判断,后面if-else月写越多显得十分的乱。在网上简单查了一下解决方法,果然有不少干货,感觉最经典最简洁的还是使用策略模式来重构过多的if-else 选择。

首先我们新建一个interface

public interface InnerCommand {
void process(String msg);
}

   然后把每一个if逻辑都单独抽取到一个类里面如

/**
* @author lee.
* @date 2019/5/24 15:53
*/
@Service
public class PrintAdminCommand implements InnerCommand {
@Override
public void process(String msg) {
System.out.println("PrintAdminCommand");
}
}

这里就不一一列举了。

然后我们这里新建一个enum CommonCode

/**
* @author lee.
* @date 2019/5/24 15:51
*/
public enum CommonCode { USER("user", "用户", "com.yumstone.invoiceapply.Command.impl.PrintUserCommand"),
ADMIN("admin", "管理员", "com.yumstone.invoiceapply.Command.impl.PrintAdminCommand");
private String code;
private String desc;
private String clazz;
private static final Map<String, String> classes = new HashMap<String, String>(); static {
for (CommonCode refer : CommonCode.values()) {
classes.put(refer.getCode(), refer.getClazz());
}
} CommonCode(String code, String desc, String clazz) {
this.code = code;
this.desc = desc;
this.clazz = clazz;
} public static Map<String, String> getAllClazz() {
return classes;
}
public static String getDescByCode(int code) {
return classes.get(code);
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}

这里我们可以看到枚举类里面有一个静态代码块在程序一开始执行的的时候就会把类和对应的code 加载到内存中。

再然后我们新建一个组件处理根据不同的code获取不同的处理类,

/**
* @author lee.
* @date 2019/5/24 15:59
*/
@Component
public class InnerCommandContext {
@Autowired
ApplicationContext applicationContext; public InnerCommand getInstance(String command) {
//getAllClazz
Map<String, String> allClazz = CommonCode.getAllClazz();
String clazz = allClazz.get(command);
InnerCommand innerCommand = null;
try {
if (clazz==null||clazz.length()==0) {
clazz = PrintAdminCommand.class.getName() ;
}
innerCommand = (InnerCommand)applicationContext.getBean(Class.forName(clazz));
} catch (Exception e) {
e.printStackTrace();
}
return innerCommand;
}
}

这里我们可以看到获取的类是通过反射在spring容器里面找到的。好了到这里我们的准备工作就做完了最后写我们的逻辑部分。

/**
* @author lee.
* @date 2019/5/24 16:06
*/
@RestController
public class TextController {
@Autowired
InnerCommandContext innerCommandContext;
@RequestMapping("text")
public String test(@RequestParam String name){
InnerCommand innerCommand = innerCommandContext.getInstance(name);
innerCommand.process(name);
return "ok" ;
}
}

是不是特别简洁 原来可能很多if-else 的判断现在被优化成了两行代码

  InnerCommand innerCommand = innerCommandContext.getInstance(name);
innerCommand.process(name);
总结程序在启动的时候会把所有的逻辑类的类名加载到内存中,然后通过code找到所需的类型通过反射构建出来,最后就可以执行所需要处理的业务了,在新增一个逻辑只需要新增一个 InnerCommand 的实现类并且添加到枚举类里面去就行了。然后就可以通过该类型的code来获取。

策略模式,重构if-else的更多相关文章

  1. 使用策略模式重构switch case 代码

    目录 1.背景 2.案例 3.switch…case…方式实现 4.switch…case…带来的问题 5.使用策略模式重构switch…case…代码 6.总结 1.背景 之前在看<重构    ...

  2. java设计模式--策略模式

    策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 本文地址:http:// ...

  3. 理解javascript中的策略模式

    理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...

  4. JavaScript设计模式与开发实践 - 策略模式

    引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...

  5. 《JavaScript设计模式与开发实践》读书笔记之策略模式

    1.策略模式 定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换 1.1 传统实现 根据工资基数和年底绩效来发送年终奖 var calculateBonus= function (perfo ...

  6. JavaScript设计模式_02_策略模式

    在程序设计中,我们常常遇到这种情况,要实现某一个功能我们有很多种算法可以实现.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是所谓的策略模式. /* * pre:策略模式 * 示例:公司计算奖 ...

  7. javascript设计模式——策略模式

    前面的话 在程序设计中,常常遇到类似的情况,要实现某一个功能有多种方案可以选择.比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法.这些算法灵活多样,而且可以随意互相替换.这种解决方 ...

  8. JavaScript设计模式之策略模式

    所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...

  9. JavaScript设计模式 Item 7 --策略模式Strategy

    1.策略模式的定义 何为策略?比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但是不在乎钱,可以选择坐飞机. 如果没有钱,可以选择坐大巴或者火车. 如果再穷一点,可以选 ...

  10. 《JavaScript设计模式与开发实践》-- 策略模式

    详情个人博客:https://shengchangwei.github.io/js-shejimoshi-celue/ 策略模式 1.定义 策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们 ...

随机推荐

  1. selenium定位方法-iframe元素定位方法

    在自动化测试中,如果无法定位到一个元素,那么最大的可能是定位的元素是在iframe框架中,iframe对象代表一个HTML的内联框架,在HTML中,iframe每出现一次,一个iframe对象就会被创 ...

  2. C#中的@和$ 占位符

    c#中@的三种用法: 1.忽略转移字符 string str = "C:\\windows\\system32"; string str = @"C:\windows\s ...

  3. DB技能数据库里把技能伤害调整

    1. MagID 技能代号 2. MagName 技能名称 3. Effect Type 效果类型(使用技能时角色的动作效果) 4. Effect 效果(技能产生的动画效果) 5. Spell 每次耗 ...

  4. 查看Oracle的SID的方式

    1  使用组合键“Win + R”打开运行对话框,在输入框中输入 regedit 并回车打开“注册表编辑器”. 2   在“注册表编辑器”对话框,依次展开 HKEY_LOCAL_MACHINE\SOF ...

  5. Gym-TORCS安装

    系统为Ubuntu16.04来安装Gym-TORCS 安装pip: sudo apt-get install python-pip sudo pip install --upgrade pip 安装p ...

  6. FreeRTOS学习笔记3:内核控制及开启调度器

    内核控制函数API 应用层中不会用到taskYIELD() //任务切换.会自动切换当前就绪表里优先级最高的任务 临界区 //不能被打断的代码段任务中进入临界区任务中退出临界区中断服务进入临界区中断服 ...

  7. QQ发起聊天

    QQ推广 网址: http://shang.qq.com/v3/widget.html 一键加群 实例: <a target="_blank" href="//sh ...

  8. 每天进步一点点------基础实验_13_有限状态机 :Mealy型序列检测器

    /********************************************************************************* * Company : * Eng ...

  9. 使用Docker搭建Spark集群(用于实现网站流量实时分析模块)

    上一篇使用Docker搭建了Hadoop的完全分布式:使用Docker搭建Hadoop集群(伪分布式与完全分布式),本次记录搭建spark集群,使用两者同时来实现之前一直未完成的项目:网站日志流量分析 ...

  10. (爬虫)随机生成一个header

    #!/usr/bin/env python #-*- coding: utf-8 -*- #__Author__: yunrui #__Version__: 1.0 #__Time__: 2019/1 ...