一、待解决问题: 减少代码中 if else 语句,降低代码圈复杂度或深度,增强可读性。
1、需求背景: 采购订单创建,需要验证采购员、物料、供应商、供应商的银行账号等信息。如采购员权限到期、或供应商失效等问题,都无法下单。
2、代码如下:
public class PurchaseOrderHandler {
public boolean isBuyerPermissionSupport(PurchaseOrderEntity orderEntity) {
}
public boolean isSupplierValid(PurchaseOrderEntity orderEntity) {
}
public boolean isItemAllowed(PurchaseOrderEntity orderEntity) {
}
public boolean isSupplierBankAccountValid((PurchaseOrderEntity orderEntity) {
}
public String createPurchaseOrder(PurchaseOrderEntity orderEntity) {
if (!isBuyerPermissionSupport(orderEntity)) {
return "buyer has no permission";
}
if (!isItemAllowed(orderEntity)) {
return "item is not allowed";
}
if (!isSupplierValid(orderEntity)) {
return "supplier is not valid";
}
if (!isSupplierBankAccountValid(orderEntity)) {
return "supplier bank account is not valid";
}
/**
* 创建逻辑省略。。。。。。
*/
return "create Success";
}
}
学习使用责任链模式后优化:
public abstract class Handler {
public Handler successor;
public abstract boolean isValid(PurchaseOrderEntity orderEntity);
public void setSuccessor(Handler handler) {
successor = handler;
}
}
public class BuyerHandler extends Handler{
@Override
public boolean isValid(PurchaseOrderEntity orderEntity) {
if ("xxxBuyer".equals(orderEntity.getBuyer())) {
return false;
} else {
return successor.isValid(orderEntity);
}
}
}
public class ItemHandler extends Handler{
@Override
public boolean isValid(PurchaseOrderEntity orderEntity) {
if ("xxxxItem".equals(orderEntity.getItem())) {
return false;
} else {
return successor.isValid(orderEntity);
}
}
}
/**省略供应商和供应商银行账号的校验类 **/
public class PurchaseOrderHandler {
public String createPurchaserOrder(PurchaseOrderEntity orderEntity) {
Handler buyerHandler = new BuyerHandler();
Handler itemHandler = new ItemHandler();
Handler supplierHandler = new SupplierHandler();
Handler supplierBankAccountHandler = new SupplierBankAccountHandler();
Handler lastHandler = new SupplierHandler();
buyerHandler.setSuccessor(itemHandler);
itemHandler.setSuccessor(supplierHandler);
supplierHandler.setSuccessor(supplierBankAccountHandler);
supplierBankAccountHandler.setSuccessor(lastHandler);
if (!buyerHandler.isValid(orderEntity)) {
return "purchase order create error.";
}
return "create Success";
}
}
3、分析:使用责任链模式,将整体的校验流程和具体校验点逻辑实现分离,但是每增加一个校验点,就要新增一个实现类。
二、责任链模式:
为避免发送者与多个请求处理者耦合在一起,将所有的请求处理者通过前一对象记住其下一个对象的引用而连城一条链。当请求发生时,可将请求沿着这条链传递,直接有对象处理它为止。
备注:从这个概念看,责任链模式主要用于解决为请求找到合适的处理对象。经典案例是请假问题,如请假3天组长审批,5天项目经理审批,7天部长审批。组长、项目经理、部长属于不同的对象。
1、主要角色:
抽象处理者(handler):包含处理请求的接口、抽象处理方法和后继节点。
具体处理者(Concrete handler):继承实现抽象处理者并实现请求的接口。可以处理请求则处理,不能处理则转给后继节点。
客户端角色(client):创建处理链,并向具体的处理对象提交请求。
类图:
2、优点:
1、减低对象之间的耦合度。
2、增强系统的可扩展性,满足开闭原则。
3、简化了处理对象的链接,避免过多的 if else 语句。
4、责任分担。每个类只处理自己的逻辑,明确责任范围,符合类的单一职责原则。
3、缺点:
1、每个处理对象要创建一个类,造成类过多。
2、使用客户端角色创建责任链。如果责任链的继任者设置错误,可能造成循环调用。
3、当责任链过长,请求处理涉及多个处理对象,无法使用并发,系统性能受到影响。
三、实际项目感悟:
1、责任链模式主要用于解决为请求找到合适的处理对象。本文中的案例使用责任链解决校验逻辑多造成的 if else 语句过多问题,可能并不是一个好的主意。因为这样造成了过多的类对象,并且不相关校验逻辑不能使用并发校验。这种场景需要找到一个更合适的方案解决。
2、责任链会使代码增多。文章来源:https://www.toymoban.com/news/detail-497936.html
学习自B站课程: https://www.bilibili.com/video/BV1Np4y1z7BU?p=105文章来源地址https://www.toymoban.com/news/detail-497936.html
到了这里,关于设计模式—责任链模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!