请将你的 if else 设计成责任链模式!

JAVA herman 243浏览 0评论

我只想问你一句,你真的懂 if else 吗?真的懂设计模式吗?真的是高级开发亦或是架构师吗?请看看你的代码 if else 已超过 200 行了。类似的还有 switch case,这样的设计和做法在日常中已经举不胜举。我恳请你淘汰这样的做法,也请你将你的 if else 设计成责任链模式。

当然并不是要把所有的 if else(switch case 也类似,下面就只用 if else 做说明)都改成责任链。至于如何判断是不是要设计成责任链模式,我想说没有标准,就像拆分微服务一样。

虽然没有标准,但是并不代表没有规则。如果你的 if else 设计的违反了“单一职责原则”、“开闭原则”等那就可以进行责任链模式设计。

下面我列举一个例子,来说明。

就拿我们公司来说,有一个采购审批业务。业务处理流程如下图:

责任链模式

采购人员提交一个单子后,需要经过主任、副董事长、董事长、董事会进行审批。如果我们按照 if else 的方式编码,代码就如下面所示:

//采购单处理类  
public class PurchaseApprovalHandler {  
    //递交采购单给主任  
    public void doApproval(PurchaseRequest request) {  
        if (request.getAmount() < 50000) {  
            //主任可审批该采购单  
            this.handleByDirector(request);  
        } else if (request.getAmount() < 100000) {  
            //副董事长可审批该采购单  
            this.handleByVicePresident(request);  
        } else if (request.getAmount() < 500000) {  
            //董事长可审批该采购单  
            this.handleByPresident(request);  
        } else {  
            //董事会可审批该采购单  
            this.handleByCongress(request);  
        }  
    }  
      
    //主任审批采购单  
    public void handleByDirector(PurchaseRequest request) {  
        //代码省略  
    }  
      
    //副董事长审批采购单  
    public void handleByVicePresident(PurchaseRequest request) {  
        //代码省略  
    }  
      
    //董事长审批采购单  
    public void handleByPresident(PurchaseRequest request) {  
        //代码省略  
    }  
      
    //董事会审批采购单  
    public void handleByCongress(PurchaseRequest request) {  
        //代码省略  
    }  
}  

看似很完美,但实际上后续维护会存在很多问题。比如,当前这个类业务过于复杂。各级别的审批方法都集中在一个类中,违反了“单一职责原则”。

功能虽然没有问题,但是维护麻烦。为了不违反“单一职责原则”,我们也可以将业务拆分为多个类。但是现在我又有新的需求了,新增一个审批节点,或者调整某一节点的审批额度范围,必须对源代码进行修改,同时需要进行严格的测试。现在你还觉得上面的设计方式好吗?是不是感觉上面的设计违反了“开闭原则”。

现在我告诉你并没有完美无缺的代码和架构设计,就像高内聚和低耦合一样,我们只要掌握好平衡即可。下面我们将上面的 if else 模式改为责任链模式看看是否符合设计原则。

再开始之前,我们先来看一下责任链模式的结构图:

责任链模式

按照上面的结构图,我们照葫芦画瓢即可。需要说明的一点是,责任链模式我相信大家都不模式了,但是大多数人理解它,就是不会用,或者说不知道用在什么样的场景,所以上图中的每个类我就不在细说,直接略过。

按照上图,我们先抽象一个 Handler,代码如下:

abstract class Handler {  
    //维持对下家的引用  
    protected Handler successor;  
      
    public void setSuccessor(Handler successor) {  
        this.successor=successor;  
    }  
      
    public abstract void handleRequest(String request);  
}

然后就是 Handler 的实现类,也就是审批处理类:

public class ConcreteHandler extends Handler {  
    public void handleRequest(String request) {  
        if (请求满足条件) {  
            //处理请求  
        }  else {  
            this.successor.handleRequest(request);  //转发请求  
        }  
    }  
} 

伪代码写完后,是不是感觉和上面没什么区别。是的功能上是没有什么区别,但是在代码的维护上更方便,也更符合我们的设计原则。

常见的符合责任链模式的还有处理各种请求报文,例如 dubbo 中的用到的责任链模式。

学习责任链模式,我们更多的是要用,而不是为了学习而学习!

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847,QQ3群:187424846。QQ群进群密码:xttblog,想加微信群的朋友,可以微信搜索:xmtxtt,备注:“xttblog”,添加助理微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 请将你的 if else 设计成责任链模式!