资讯专栏INFORMATION COLUMN

从实践学习设计模式——优化多if代码结构

马永翠 / 2473人阅读

摘要:拓展模板方法模式回头看看上面责任链模式的代码,抽象类中定义了几个方法,一个是修饰的,一个是抽象方法,还有一个是。

前情提要

在实际开发中,我们常常会出现以下的代码情况:

        if (state == 1){
            haveBreakfast();
        } else if (state == 2){
            haveLunch();
        } else if (state == 3){
            haveDinner();
        }

这种代码结构是不是很糟糕,如果未来又有一个新状态加入,则又要加入一个新的else if语句,如此往复,则会产生一个非常糟糕的代码结构体。

那么该如何优化这串代码呢?这里有两种方式:一种是使用责任链模式,一种是使用策略模式

我们先来看看责任链模式是如何优化这串代码的:

责任链模式

首先上UML类图:

设计代码:

public abstract class Handler {
    private Handler nextHandler;
    private int state;
    
    public Handler(int state) {
        this.state = state;
    }

    // 处理请求传递,注意final,子类不可重写
    public final void handleMessage(int state) {
    // 传递状态是否符合,不符合走下一级
        if (this.state == state) {
            this.report();
        } else {
            if (this.nextHandler != null) {
                // 交给下级处理
                this.nextHandler.handleMessage(demand);
            } else {
                System.out.println("没有下级可处理");
            }
        }
    }

    public void setNextHandler(Handler handler) {
        this.nextHandler = handler;
    }

    // 抽象方法,子类实现
    // 这里也用了模板方法设计模式
    public abstract void report();
}

public class HaveBreakfast extends Hanlder {
    public HaveBreakfast(){
        super(1);
    }
    
    public void report(){
        System.out.println("我在吃早餐");
    }
}

public class HaveLunch extends Hanlder {
    public HaveLunch(){
        super(2);
    }
    
    public void report(){
        System.out.println("我在吃中餐");
    }
}

public class HaveDinner extends Hanlder {
    public HaveDinner(){
        super(3);
    }
    
    public void report(){
        System.out.println("我在吃晚餐");
    }
}

主类实现:

public class Client {
    public static void main(String[] args) {
        // 初始化
        HaveBreakfast breakfast = new HaveBreakfast();
        HaveLunch lunch = new HaveLunch();
        HaveDinner dinner = new HaveDinner();
        
        // 设置下一级
        lunch.setNextHandler(dinner);
        breakfast.setNextHandler(lunch);
        
        // 我要吃中餐
        int lunchState = 2;
        breakfast.report(lunchState);
        // 我要吃晚餐
        int dinnerState = 3;
        breakfast.report(dinnerState);
    }
}

用责任链模式实现了代码的解耦,以后只要根据state值的不同,调用breakfast.report(state)即可。

策略模式

同样上UML类图:

设计代码:

public interface Strategy {
    public void algorithm();
}

public class HaveBreakfast implements Strategy{

    public void algorithm() {
        System.out.println("我在吃早餐");
    }
    
}

public class HaveLunch implements Strategy{

    public void algorithm() {
        System.out.println("我在吃中餐");
    }
    
}

public class HaveDinner implements Strategy{

    public void algorithm() {
        System.out.println("我在吃晚餐");
    }
    
}

public class Context implements Strategy{
    private Strategy strategy;
    private final Map map = new HashMap<>();
    
    public void setStrategy(int state) {
        initMap();
        this.Strategy = this.map.get(state);
    }
    
    private void initMap() {
        this.map.put(1, new HaveBreakfast());
        this.map.put(2, new HaveLunch());
        this.map.put(3, new HaveDinner());
    }
    
    public void algorithm() {
        this.strategy.algorithm();
    }
}

实现代码:

public class Client {
    public static void main(String[] args) {
        Context context = new Context();
        // 我要吃中餐
        int lunchState = 2;
        context.setStrategy(lunchState);
        context.algorithm();
        // 我要吃晚餐
        int dinnerState = 3;
        context.setStrategy(dinnerState);
        context.algorithm();
    }
}

用策略模式也同样实现了代码的解耦。

策略模式 VS 责任链模式

通过以上分析,我们知道使用责任链模式和策略模式都能解耦杂乱的if-else代码,但两者又有什么不同,实际开发中我们该选用那种?结论是责任链是一种链式结构的处理方式,是有层级性的,而策略模式并没有层级关系,选用哪种可根据开发需求进行定夺。

拓展——模板方法模式

回头看看上面责任链模式的代码,Handler抽象类中定义了几个方法,一个是final修饰的handleMessage,一个是抽象方法report,还有一个是setNextHandler。这三个分别对应模板方法模式中的三个基本方法,分别是具体方法handleMessage(抽象类声明并实现,子类不实现)、抽象方法report(抽象类声明,子类必须实现)、钩子方法setNextHandler(抽象类声明并实现,子类可扩展)。
这样结合模板方法模式的好处在哪?首先加了handleMessage方法,把请求的传递判断从子类中剥离出来,让子类在report方法中专心处理请求的业务逻辑,做到了单一职责原则。子类的实现只要继承该抽象类即可,非常简单。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72603.html

相关文章

  • 小白程序员一路晋升为大厂高级技术专家我看过哪些书籍?(建议收藏)

    摘要:大家好,我是冰河有句话叫做投资啥都不如投资自己的回报率高。马上就十一国庆假期了,给小伙伴们分享下,从小白程序员到大厂高级技术专家我看过哪些技术类书籍。 大家好,我是...

    sf_wangchong 评论0 收藏0
  • 【转】成为Java顶尖程序员 ,看这10本书就够了

    摘要:实战高并发程序设计这本书是目前点评推荐比较多的书,其特色是案例小,好实践代码有场景,实用。想要学习多线程的朋友,这本书是我大力推荐的,我的个人博客里面二十多篇的多线程博文都是基于此书,并且在这本书的基础上进行提炼和总结而写出来的。 学习的最好途径就是看书,这是我自己学习并且小有了一定的积累之后的第一体会。个人认为看书有两点好处:showImg(/img/bVr5S5);  1.能出版出...

    DTeam 评论0 收藏0
  • 学习JVM必看书籍

    学习JVM的相关资料 《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》 showImg(https://segmentfault.com/img/bVbsqF5?w=200&h=200); 基于最新JDK1.7,围绕内存管理、执行子系统、程序编译与优化、高效并发等核心主题对JVM进行全面而深入的分析,深刻揭示JVM的工作原理。以实践为导向,通过大量与实际生产环境相结合的案例展示了解...

    shaonbean 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<