【设计模式实战】用三种设计模式去优化if-else屎山代码!!!

优化前提


前言

我们之前也学习了不少设计模式,今天给大家介绍一个案例,帮助大家更加熟悉设计模式,并能够在自己写项目的时候能够下意识的使用设计模式,避免写出屎山代码。🌈

提示:不清楚策略、工厂、模板方法模式的小伙伴可以参考上方文章。


一、 抛出屎山代码

我就以一个简单的代码模拟下业务,像我们平时写项目的时候,这种if-else语句非常常见,比如说:在判断支付类型的时候,在参数校验的时候等等。过多的if-else,会使代码冗余、可读性不好,最重要的是违反了“开闭原则”,拓展性非常的差,后面的同事看了后会非常的痛苦,内心一顿臭骂,为了避免被后面的同事吐槽谩骂,我们要写出更加优雅的代码。

void Example1(){
        String name = "小杰";
        if (name.equals("刘二")){
            System.out.println("刘二完成任务");
        } else if (name.equals("张三")) {
            System.out.println("张三完成任务");
        } else if (name.equals("李四")) {
            System.out.println("李四完成任务");
        } else if (name.equals("王五")) {
            System.out.println("王五完成任务");
        } else if (name.equals("赵六")) {
            System.out.println("赵六完成任务");
        } else if (name.equals("苏七")) {
            System.out.println("苏七完成任务");
        }
    }

二、如何解决

我们一步步引入设计模式,帮助大家理解

1.使用策略模式

分析代码

我们可以将if里面执行的代码可以看作一个个不同的策略,这样我们就可以引入策略模式去优化下面代码。

优化代码

首先,我们定义一个策略接口。

public interface Handler extends InitializingBean {
    void show();
}

实现具体的策略

public class LiSi implements Handler{
    //执行相应的策略
    @Override
    public void show() {
        System.out.println("李四完成了任务");
    }
    //这个方法是策略类初始化后需要执行的逻辑,这个我们先不管
    @Override
    public void afterPropertiesSet() throws Exception {
        Factory.register("李四",this);
    }
}

......

优化后代码

void OnlyStrategy(){
        String name = "小杰";
        if (name.equals("刘二")){
            new LiuEr().show();
        } else if (name.equals("张三")) {
            new ZhangSan().show();
        } else if (name.equals("李四")) {
            new LiSi().show();
        } else if (name.equals("王五")) {
            new WangWu().show();
        } else if (name.equals("赵六")) {
            new ZhaoLiu().show();
        } else if (name.equals("苏七")) {
            new SuQi().show();
        }
    }

2.引入工厂模式

分析代码

虽然我们引入了策略模式,但是仍然未解决if-else语句,并且每次使用策略都必须先new出来,后续拓展仍然需要添加if-else代码,这样看起来代码更加复杂了,性能更差了。别急,我们继续添加工厂模式,继续优化代码。

优化代码

我们定义一个工厂,让工厂帮我们去生产对应的对象。

public class Factory {
    //我们将策略类存入HashMap里面
    private static Map<String, Handler> map = new HashMap<>();

    //根据name获取对应的策略类
    public static Handler getInvokeStrategy(String name){
        return map.get(name);
    }
    //将策略类放入map里面
    public static void register(String name,Handler handler){
        if (StringUtils.isEmpty(name) || null == handler){
            return;
        }
        map.put(name,handler);
    }
}

这里给大家解释afterPropertiesSet()方法里面的逻辑

public class LiSi implements Handler{
    @Override
    public void show() {
        System.out.println("李四完成了任务");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        //策略类初始化后,自动将策略类注册到HashMap里面
        Factory.register("李四",this);
    }
}

优化后代码

//我们成功的干掉了if-else
void haveFactory(){
        String name = "张三";
        Handler handler = Factory.getInvokeStrategy(name);
        handler.show();
    }

3.引入模板方法模式

分析代码

到这里虽然我们成功的干掉了if-else语句,但是又引出了一个问题,

 String name = "小杰";
        if (name.equals("刘二")){
            System.out.println("刘二完成任务");
        } else if (name.equals("张三")) {
            System.out.println("张三完成任务");
        } else if (name.equals("李四")) {
            System.out.println("李四完成任务");
        } else if (name.equals("王五")) {
            return "王五完成了任务";
        } else if (name.equals("赵六")) {
            return "赵六完成任务";
        } else if (name.equals("苏七")) {
            return "苏七完成任务";
        }

我们可以看到,五五、赵六、苏七策略跟其他语句的策略并不一样。

解决思路:

  1.  在策略接口添加不同的策略(不使用)
  2. 使用模板方法模式,每个策略类实现自己对应的策略(推荐使用)

给大家解释下为什么不使用第一种,如果我们在策略接口添加不同的策略,我们的策略类就必须要实现所以的策略,但是策略类并不需要实现所有的策略,它只需要实现自己的那一个策略,所以这个思路不可行。

优化代码

我们将策略接口改为策略抽象类

public abstract class AbstractHandler implements InitializingBean {
    //策略1
    public void show(String name){ throw new UnsupportedOperationException();}
    //策略2
    public String eat(String name){ throw new UnsupportedOperationException();}
}

当然,我们的工厂和策略类也要修改,张三策略类和王五策略类实现不同的策略。


//策略工厂
public class Factory2 {
    //将Handler改为AbstractHandler
    private static Map<String, AbstractHandler> map = new HashMap<>();

    public static AbstractHandler getInvokeStrategy(String name){
        return map.get(name);
    }
    public static void register(String name,AbstractHandler handler){
        if (StringUtils.isEmpty(name) || null == handler){
            return;
        }
        map.put(name,handler);
    }
}
//张三策略类
@Component
public class WangWu extends AbstractHandler {

    @Override
    public String eat(String name) {
        return "王五吃东西";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Factory2.register("王五",this);
    }
}
//王五策略
@Component
public class ZhangSan extends AbstractHandler {

    @Override
    public void show(String name) {
        System.out.println("张三完成了任务");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Factory2.register("张三",this);
    }
}
......

优化后代码

 @Test
    void haveTemplate(){
        String name1 = "王五";
        AbstractHandler handler1 = Factory2.getInvokeStrategy(name1);
        System.out.println(handler1.eat(name1));
        String name2 = "张三";
        AbstractHandler handler2 = Factory2.getInvokeStrategy(name2);
        handler2.show(name2);
    }

随着通过我们一步步的添加设计模式,使我们的代码更加简洁,也符合了“开闭原则”,到这里,我们就优化完成了。


总结

        虽然设计模式帮助我们优化了代码,是代码更加的规范,但是,切不可为了使用设计模式而去使用设计模式,在某种业务场景使用if-else语句可能比设计模式更加适合,所以大家要结合业务场景,选出最优的解决方法。

今天的分享就到这里,喜欢的小伙伴可以一键三连哦,我们下期再见。✋✋✋

### 回答1: 对于多个ifelse设计模式优化,可以考虑使用策略模式或状态模式来替代ifelse语句,从而提高代码的可读性和可维护性。此外,也可以使用switch语句来替代ifelse语句,但需要注意switch语句的性能问题。另外,可以考虑将ifelse语句封装成函数或方法,从而提高代码的复用性和可测试性。 ### 回答2: 多个if-else语句的设计模式优化可以通过以下几种方法来实现。 首先,可以使用策略模式来替代多个if-else语句。 策略模式允许我们根据不同的情况选择不同的策略进行处理,从而避免了多个if-else语句的嵌套。我们可以为每种情况定义一个具体的策略类,在使用时只需要根据情况选择相应的策略即可。 其次,可以使用状态模式来替代多个if-else语句。 状态模式将对象的行为封装在不同的状态类中,根据对象的状态来选择不同的行为,从而避免了多个if-else语句的使用。 另外,可以使用责任链模式来优化多个if-else语句。 责任链模式将多个处理对象组成一个链表,每个对象都有机会处理请求,如果某个对象能够处理请求,则直接处理;如果不能处理,则将请求传递给下一个对象,直到有对象能够处理为止。 最后,可以使用工厂模式来替代多个if-else语句。 工厂模式将对象的创建和使用解耦,通过工厂来创建对象,从而避免了多个if-else语句的使用。我们可以定义一个工厂类,根据不同的情况来创建相应的对象,而不需要在代码中使用多个if-else语句。 综上所述,通过使用策略模式、状态模式、责任链模式和工厂模式等设计模式,我们可以优化多个if-else语句,并且提高代码的可扩展性和可维护性。 ### 回答3: 多个ifelse设计模式经常出现在代码中,给代码的可读性和可维护性带来了困扰。为了优化这个设计模式,可以采取以下几种方法。 1. 使用策略模式:将每个ifelse语句块封装到不同的策略类中,每个策略类实现一个共同的接口或继承一个抽象类。然后将策略类的实例作为参数传递给调用者,调用者根据需要选择不同的策略类进行处理。 2. 使用工厂模式:将每个ifelse语句块中的逻辑抽象成不同的工厂类,在每个工厂类中进行条件判断并创建对应的对象或执行相应的逻辑。这样可以将复杂的条件判断逻辑封装在各个工厂类中,提高代码的可读性和可维护性。 3. 使用链式调用:将多个ifelse语句块拆分成多个条件判断的方法,并使用链式调用的方式进行组合。每个条件判断方法返回调用者自身的实例,使得可以在一个方法中进行多个条件判断。这样可以将多个ifelse语句块转化成一条链式调用,提高代码的可读性和可维护性。 4. 使用状态模式:将多个ifelse语句块中的逻辑抽象成不同的状态类,每个状态类表示一种状态。它们共同实现一个共同的接口或继承一个抽象类,并在接口或抽象类中定义相应的操作方法。然后根据不同的条件进行状态切换,调用相应状态的操作方法。 以上是优化多个ifelse设计模式的一些常见方法,选择适合自己项目的方式可以提高代码的可读性和可维护性,减少ifelse语句块带来的问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杰不秃头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值