什么是责任链?

什么是责任链?责任链模式是行为模式的一种,它将需要触发的handler组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个handler来处理它或者直到最后也没有对象处理而留在链末尾端;责任连模式的重点是在链上,由一条链去处理相似的请求,在链中决定谁来处理这个请求
责任链分为纯责任链与不纯责任链(一般实战应用较多)
**纯职责链 **1.每个处理者接收到请求后,要么单纯转发请求,要么单纯处理请求。不允许既处理请求,又转发请求的情况。2.请求必须被责任链上的某个处理者处理。不允许出现请求未被处理的情况。**不纯职责链 **1.每个处理者接收到请求后,除了单纯转发请求,或者单纯处理请求,还可以部分处理请求后,转发。2.请求可以不被责任链上的任何处理者处理。责任链优点1.解耦请求者和处理者。2.非常灵活,可以任意组装3.各个节点的责任明确缺点1.每次都是从链头开始。2. 可能造成死循环。责任链如果是环状的,可能会导致循环调用,造成死循环。纯责任链的代码demo:
/** * 在公司oa系统请假审批流程如果请假小于3天只需要项目经理批复就行;如果请假大于等于3天,小于7天需要人事经理批复了;如果请假大于等于7天,小于15天需要总经理批复了;如果申请请假大于等于15天,决绝批复...... * @param args */ public static void main(string[] args) { leader manager = new manager(张三); leader hrmanager = new hrmanager(李四); leader generalmanager = new generalmanager(王麻子); //组织责任链对象的关系 manager.setnextleader(hrmanager); hrmanager.setnextleader(generalmanager); //请假 leaverequest request = new leaverequest(parry, 10, 回家相亲!); manager.dealleaverequest(request); }public abstract class leader { // 领导姓名 protected string name; // 责任链上的后继对象 protected leader nextleader; public leader(string name) { super(); this.name = name; } public void setnextleader(leader nextleader) { this.nextleader = nextleader; } public abstract void dealleaverequest(leaverequest request);} public class hrmanager extends leader{ public hrmanager(string name) { super(name); } @override public void dealleaverequest(leaverequest request) { if (3 <= request.getleaveday() && request.getleaveday() < 7) { system.out.println(人事经理: + name + 审批了 + request.getemployee() + 请假 + request.getleaveday() + 天的请求,请假原因: + request.getreason()); } else { if (this.nextleader != null) { this.nextleader.dealleaverequest(request); } } }}public class generalmanager extends leader { public generalmanager(string name) { super(name); } @override public void dealleaverequest(leaverequest request) { if (7 <= request.getleaveday() && request.getleaveday() <= 15) { system.out.println(总经理: + name + 审批了 + request.getemployee() + 请假 + request.getleaveday() + 天的请求,请假原因: + request.getreason()); } else { system.out.println( 总经理: + name + 拒绝了 + request.getemployee() + 请假 + request.getleaveday() + 天的请求,请假不能超过15天); } }}public class manager extends leader{ public manager(string name) { super(name); } @override public void dealleaverequest(leaverequest request) { if (request.getleaveday() 商家审核——>完成
退款退货:采购商申请——>商家审核——>采购商发货——>商家确认收货——>完成
退款换货:采购商申请——>商家审核——>采购商发货——>商家确认收货——>商家发出新品——>采购商确认收货——>完成
仅退款的实际退款等操作在商家审核时,而退款退货和退款换货则在确认收货时。
以下为售后责任链流程:
售后->校验退款单状态->原路退款(以下单支付方式为准)->退积分或其它优惠->更新订单及对应商品退款信息->保存结算->保存财务流水->保存/更新退款日志->发送退款成功异步消息
三种售后的核心退款业务流程基本是一致的,少个别节点业务逻辑有所区别,将核心业务抽成责任链的各个节点,这对售后来说,代码的复用性提高了很多,同时业务处理更加清晰,犯错率大大降低。
以下为售后中代码使用demo
定义一个节点的基类接口
public interface baserefundhandler { void handle(pipelinecontext context); }售后责任链组装,以下以仅退款为例
public class refundpipebean {/** * 仅退款,责任链初始化节点 */public list refundpipe = new arraylist(); public list getrefundpipe() { refundpipe.add(checkrefundstatus); //校验退款单状态 refundpipe.add(refundmoney); //原路退款(获取订单支付方式) refundpipe.add(returnscore); //退积分或其它优惠券类 ...... return refundpipe; } @bean @scope(prototype) public checkrefundstatus checkrefundstatus() {return new checkrefundstatus();} @bean @scope(prototype) public refundmoney refundmoney() {return new refundmoney();} ......}** 注: 这个配置就等同于之前在xml里的配置**
创建一个启动监听器
@componentpublic class refundpipelistener extends applicationobjectsupport implements initializingbean { private static map handlersmap = new hashmap(); public static map gethandlersmap() { return handlersmap; } //最好定义成全局的,此处因演示 才在类中写 。 责任链的名称 public static string only_refund=only_refund; @override public void afterpropertiesset() throws exception { refundpipebean refundpipebean=new refundpipebean(); //装载退款业务链..... list normalhandlers=new arraylist(); for (string s : refundpipebean.getrefundpipe()) { baserefundhandler normalhandler = (baserefundhandler) getapplicationcontext().getbean(s); normalhandlers.add(normalhandler); handlersmap.put(only_refund, normalhandlers); } }}创建节点传递对象所用pojo类
@datapublic class pipelinecontext extends concurrenthashmap { protected boolean success = false; //责任链结束标识 protected boolean isend = false; protected string resultcode; private object data; public boolean issuccess() { return success; } public void setsuccess(boolean success) { this.success = success; } public boolean isend() { return isend; } public void setend(boolean end) { isend = end; }}public class refundpipelinecontext extends pipelinecontext { /** * 封装退款单信息 */ private refundinfopipevo refundinfopipevo; public refundinfopipevo getrefundinfopipevo() { return refundinfopipevo; } public void setrefundinfopipevo(refundinfopipevo refundinfopipevo) { this.refundinfopipevo = refundinfopipevo; }}创建节点
public class checkrefundstatus implements baserefundhandler { @override public void handle(pipelinecontext context) { //业务逻辑 todo ...... //表示该节点运行正常,可以继续向下走 context.setsuccess(true); }}业务调用层
@restcontrollerpublic class refundinfocontroller { @autowired refundinfoservice refundinfoservice; @apioperation(仅退款) @requestmapping(value = /auditrefund, method = {requestmethod.get, requestmethod.post}, produces = application/json;charset=utf-8) public respdata auditrefund(xxx) { refundinfoservice.auditrefund(xxx); return respdata.success(审核成功,true); }}public interface refundinfoservice { void auditrefund(xxx);}@service(refundinfoservice)public class refundinfoserviceimpl implements refundinfoservice { @override public void auditrefund(xxx) { //业务逻辑 todo refundinforesultvo refundinforesultvo = refundinfomapper.querybyid(platformid, refundid); ...... pipelinecontext refund = new refundpipelinecontext(); //在责任链中传递参数对象 refund.put(refund, refundinforesultvo); map map = refundpipelinechangelistener.gethandlersmap(); //通过责任链的名称获取对应链 。 此处key值应为一个全局的常量,与上面监听器中的链条名一致 list baserefundhandlers = map .get(only_refund); for (baserefundhandler handler : baserefundhandlers) { handler.handle(refund); if (refund.isend()) { system.out.println(责任链执行结束...); break; } if (!refund.issuccess()) { system.out.println(责任链执行失败...); break; } } }}整体总结
以上是责任链在业务中创建及使用的流程。
同时以上流程也还存在一些可优化点:
责任链节点硬编码问题添加同步事务控制

多层pcb线路板打样难点
华为安全多项技术列入Gartner《2022中国网络安全技术成熟度曲线》
怎样使用示波器触发进行调试
分析NFC近距离无线通讯技术
大屏真的好吗?三星GalaxyA7、A5、A3摔落对比
什么是责任链?
诺基亚将重返巅峰?与T-Mobile签订价值35亿美元的5G合同
一个以无人车为代表的人工智能时代正向我们走来
EMC测试整改:确保电磁兼容性,提升产品质量?
工业机器人中示波器的重要性分析
Cydia起诉苹果在App Store垄断
康耐视托盘扫码系统保证入库物流环节的效率和吞吐量
AP8851 底压输入12-24V 大电流输出6-8A 降压恒压驱动原理图
基于J-Link Remote Server软件的远程调试方法
一文看懂ms5611性能参数及典型应用
行业前沿:驶入元宇宙
学习工业机器人控制大概要多久?
LED发展之道,如何应对市场爆发与变局之道
语音识别芯片WTK6900H-24SS的功能
现代化的数据管理平台的性能