这才是干掉ifelse的正确姿势(如何巧用设计模式干掉if-else)

责任链模式顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。复制代码需求在公司流程处理业务中,有不同的处理流程节点,在不同的节点需要发送不同的短信,用来通知下一个节点的处置人。 1发起->2审核->3处置->4结果审核->完成,每个环节还可以有退回到上一个节点的功能,而且不同的地区还可能有其他的流程节点。一开始产品只提出审核和处置两个节点需要发送短信,因此一开始的代码是这样写的。

顾名思义,责任链模式为请求创建了一个接收者对象链。这种模式给出了请求的类型,并分离了请求的发送方和接收方。这种设计模式属于行为模式。在这种模式下,每个接收器通常包含对另一个接收器的引用。如果一个对象不能处理该请求,它将把相同的请求传递给下一个接收者,依此类推。复制代码

需求

在公司流程处理业务中,有不同的处理流程节点,需要在不同的节点发送不同的短信通知下一个节点的处置者。1 -2审批-3处置-4结果审批-完成,每个环节还可以有返回上一个节点的功能,不同区域可能还有其他流程节点。最初产品只提出审核和处置节点需要发送短信,所以最初的代码是这样写的。

公开课警告smshandler { public void send SMS(){//流程发送短信逻辑if(审核是否完成){/查询处置者,设置短信内容,发送短信} else if(处置是否完成){//查询结果的审核者,设置短信内容,发送短信}}复制代码。久而久之,产品提出在发起阶段就要发短信。这时候可以选择修改原来的WarningSmsHandler类,现在实现起来比较快,但是以后也会带来一些问题:1。随着越来越多节点发送短信的需求,这个类会不断增加代码,违反了单一责任原则。2.以后添加节点的短信和删除节点的短信时,需要更改WarningSmsHandler类的代码,违反了开放封闭原则。

所以我们必须思考如何选择一个全面的计划来避免这些问题。回到需求,短信从上一个节点发送到下一个节点,通常只发送到下一个节点。这里我想到用责任链的模式来拆分各个节点发短信的逻辑,单个责任。

00-1010 1.定义统一请求类

@ datapublic类warning mshandlerrequest {//通知id private Long warningId//下一个通知状态私有警告状态枚举下一个警告状态;//下一个通知处理程序类型Private warning handleunitenum warning handleunitenum;//附加参数私有列表字符串附件参数;//短信模板id部分短信厂商需要模板私有String templateId}复制代码2。定义统一处理结果类。

@ data public class warningmshandlerresult {//已成功发送的手机号码列表Private list stringmobiles=new ArrayList();//发送是否成功私有布尔成功;}复制代码2。定义请求处理接口

/* * *短信处理器接口*/公共接口SmsHandler {//当前接口是否支持处理布尔支持(Warningsmshandlerrequest请求);//处理逻辑void句柄短信(警告smshandlerrequest请求,警告smshandleresult);}复制代码,一个具体的请求处理器实现——短信处理器在审核环节

/* * *审核阶段的短信发送逻辑*/Public类WarningIndITSMHandler实现短信处理程序{ @ Override Public Boolean Support(warningsmhandlerequest){ return request . getnextwarningstate()。等于(WarningStatusEnum。WAIT _ AUDIT);} @覆盖公共无效句柄

Sms(WarningSmsHandlerRequest request, WarningSmsHandlerResult result) { //处理审核短信 System.out.println("处理审核短信发送逻辑"); }}复制代码

一个具体请求处理器实现-处置环节短信处理器

/** * 处置环节短信发送逻辑 */public class WarningHandleSmsHandler implements SmsHandler {    @Override    public boolean support(WarningSmsHandlerRequest request) {        return request.getNextWarningState().equals(WarningStatusEnum.HANDLE);    }    @Override    public void handleSms(WarningSmsHandlerRequest request, WarningSmsHandlerResult result) {        //处理审核短信        System.out.println("处理处置短信发送逻辑");    }}复制代码

处理器写好了,怎么让他们一起串起来了? 一般的写法是每个处理器有一个设置下一个处器的方法(setNext),指定下次执行的处理器。 这种写法在有顺序要求的链路处理中比较常用,在以后修改或新增处理器都需要修改setNext方法。 在本次案例中,每个节点都会调用这个发送短信流程,每个处理器都有一个support方法,每次都会根据当前请求过滤出需要处理的处理器。

构造处理器调用链接口

public interface WarningSmsHandlerInvocation {    WarningSmsHandlerResult invoke(WarningSmsHandlerRequest request);}复制代码

构造处理器调用链接口实现

@Component@Setterpublic class WarningSmsHandlerInvocationImpl implements WarningSmsHandlerInvocation {    //通过spring注入所有SmsHandler类型的bean    @Autowired    private List<SmsHandler> smsHandlers;    @Override    public WarningSmsHandlerResult invoke(WarningSmsHandlerRequest request) {        WarningSmsHandlerResult result = new WarningSmsHandlerResult();        //依次调用所有匹配当前请求的处理器        for (SmsHandler smsHandler : smsHandlers) {            if (smsHandler.support(request)) {                smsHandler.handleSms(request, result);            }        }        return result;    }}复制代码

使用写好的处理链调用器进行测试

@Componentpublic class WarningSmsHandlerClient {    @Autowired    private WarningSmsHandlerInvocation invocation;    public void testSmsSend() {        WarningSmsHandlerRequest request = new WarningSmsHandlerRequest();        request.setNextWarningState(WarningStatusEnum.WAIT_AUDIT);        WarningSmsHandlerResult result = invocation.invoke(request);        System.out.println(result);    }}复制代码

如果需要新增一个处理器,则只要实现WarningAuditSmsHandler接口就可以了。

学会了这个设计模式,再也不是只会写if/else了


总结

通过使用责任链模式,可以降低业务代码的耦合度,提升整体的可扩展性和可维护性。

  • 每个具体处理器只要处理自己负责的业务,符合单一职责原则
  • 新增,修改,删除,都不会修改调用器的逻辑

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/152861.html

(0)

相关推荐