重构大量if-else语句: 工厂模式+策略设计模式+模板模式
程序员文章站
2022-03-10 17:12:37
重构大量if-else叠加: 工厂模式+策略设计模式+模板模式现有三个简单的if-else判断逻辑业务代码,如下图所示这种嵌套几个其实还好,但是通常开发十几个if-else确实是家常便饭if-else的数量一多,代码非常臃肿,耦合性非常高如果需要增加或者删除一个if-else...
重构大量if-else叠加: 工厂模式+策略设计模式+模板模式
现有三个简单的if-else
判断逻辑业务代码,如下图所示
这种嵌套几个其实还好,但是通常开发十几个if-else
确实是家常便饭
if-else
的数量一多,代码非常臃肿,耦合性非常高
如果需要增加或者删除一个if-else,就需要对代码进行很繁琐的修改,但是其实耐心点改起来还好,不过可能会掉头发哦
并且这种if-else
的编写破坏了设计模式六大原则中的里氏开闭原则(对拓展开放,修改关闭),不利于后续的变动和修改
为了使代码符合优雅的设计模式和编码形式,现在提供一种新的修改思路供大家参考
以下是改造前的代码:
// 三个if - else 的编码修改 @SpringBootTest class ConcurrencyApplicationTests { @Test void contextLoads() throws InterruptedException { String name = "周杰伦"; if (name.equals("周杰伦")){ for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("周杰伦出新专辑了吗"); } else if (name.equals("JJ")){ for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("小十四啥时候出哦"); } else if (name.equals("Eason")){ for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("陈老板减肥啊"); } } }
@SpringBootTest class ConcurrencyApplicationTests { @Test void contextLoads() { String name = "周杰伦"; Handler invokeStrategy = Factory.getInvokeStrategy(name); invokeStrategy.method(name); } }使用设计模式的改造方法
我们先把if
内部的业务逻辑提取出来
利用策略设计模式来编写一个接口
/**
* 策略设计模式
*/ public interface Handler extends InitializingBean { public void method(String name); }
将你的业务逻辑从if
中提取出来,写在实现类中
package com.zhou.concurrency.handler; import java.util.concurrent.TimeUnit; public class Method1Handler implements Handler { @Override public void method(String name) { for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("周杰伦啥时候发新专辑哦"); } // 这里先不用管,后面会说到 @Override public void afterPropertiesSet() throws Exception { } }剩下的几个类就省略了,其实就是复制粘贴的重复工作
将其修改成如下形式,但是这个也只是将其单独提出来,和写一个单独的函数没啥区别
@Test void contextLoads() { String name = "周杰伦"; if (name.equals("周杰伦")){ new Method1Handler().method(name); } else if (name.equals("JJ")){ new Method2Handler().method(name); } else if (name.equals("Eason")){ new Method3Handler().method(name); } }为了进一步解决
if
判断,我们使用工厂模式解决
工厂模式可以注册产品,获得产品,以及存储产品
public class Factory { // map存储参数以及其对应的Handler方法 private static Map<String, Handler> strategyMap = new HashMap<>(); // 从map中取出Handler方法,取出工厂内的产品 public static Handler getInvokeStrategy(String str) { return strategyMap.get(str); } // 将键值对注册,添加工厂产品 public static void register(String str, Handler handler) { // 如果输入进来的键值是空,不符合要求就直接返回 if (StringUtils.isEmpty(str) || handler == null) { throw new IllegalArgumentException("你输入的键值对有空值,不符合要求"); } strategyMap.put(str,handler); } }之后,修改一下之前的Handler实现类,并加入
@Component
注解,其他的几个业务逻辑同理
@Component public class Method1Handler implements Handler { // 业务逻辑 @Override public void method(String name) { for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("周杰伦啥时候发新专辑哦"); } // 类初始化自动注册 @Override public void afterPropertiesSet() throws Exception { // 这个类初始化的时候,就会自动注册 Factory.register("周杰伦",this); } }回到主函数, 改写一下即可:
@SpringBootTest class ConcurrencyApplicationTests { @Test void contextLoads() { String name = "周杰伦"; Handler invokeStrategy = Factory.getInvokeStrategy(name); invokeStrategy.method(name); } }后续如果还需要增加业务逻辑,就新增加一个Handler的实现类就好了
加模板设计方法
如果业务逻辑是两种业务逻辑,比如有的是输出一句话,有的是return一句话
那么Handler单一的method接口可能就不适用了,因为你在接口多写一个方法,其他不需要的地方你实现一个空方法,肯定要被老大骂的
@SpringBootTest class ConcurrencyApplicationTests { @Test String design(){ String name = "周杰伦"; if (name.equals("周杰伦")){ for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("周杰伦出新专辑了吗"); } else if (name.equals("JJ")){ for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("小十四啥时候出哦"); } else if (name.equals("Eason")){ for (int i = 0; i < 5; i++) { System.out.println(name + "我爱你"); } System.out.println("陈老板减肥啊"); } // 新增加的逻辑代码 返回值 else if (name.equals("jojo")){ return "欧拉欧拉欧拉欧拉"; } else if (name.equals("老大")){ return "进展如何"; } return null; } }改进一下我们的Handler类,引入模板方法模式
// 模板方法模式 public abstract class AbstractHandler implements InitializingBean { public void method(String name){ throw new UnsupportedOperationException(); } public String method2(String name){ throw new UnsupportedOperationException(); } }需要用到method就改写method,需要用到method2就改写method2
@Component public class Method4Handler extends AbstractHandler { // 业务逻辑 public String method2(String name) { return "进展如何"; } // 这里不用管 @Override public void afterPropertiesSet() throws Exception { // 这个类初始化的时候,就会自动注册 Factory.register("老大",this); } }最终代码:
@Test void contextLoads() { String name = "老大"; AbstractHandler invokeStrategy = Factory.getInvokeStrategy(name); // invokeStrategy.method(name); String s = invokeStrategy.method2(name); System.out.println(s); }本文地址:https://blog.csdn.net/qq_42669399/article/details/107889601