Chain of Responsibility  Pattern责任链模式/职责链模式是怎么一回事?-设计模式

目录

 

1、概述

(1)应用场景与实际问题

a.报销单审批

b.注册信息校验

c.购物场景

(2)责任链模式定义

a.优点

b.缺点

2、代码

(1)场景

(2)类图

(3)关键的类

3、项目源码


1、概述

(1)应用场景与实际问题

a.报销单审批

很多人工作需要出差,出差后需要填写报销单,填写后还要层层领导审批,比如直属领导-部门经理-财务主管。。。

小金额(3000以下)可能是三级审批,大金额(3000以上)可能要四级审批。而审批过程中,每一级领导都可能做出通过或驳回的操作。

与之类似的,还有各类审批单,比如采购需求单、资源申请单,等等的审批流场景。

b.注册信息校验

我们注册一个网站会员,需要校验身份证号码是否合法正确,需要校验手机号码是否有效,需要校验地址是否真实有效、需要校验头像是否与身份证上一致,等等。

c.购物场景

一个购物下单请求来了,我们需要校验库存是否够、购买权限是否正常、支付情况、物流配送单位等等。

 

以上场景,我们常常将校验逻辑写到一起,通过一堆if...else拼接。但是校验逻辑逐渐复杂,再来个新需求改动,那倒不如全部推倒重写。。。

所以,就到了责任链模式大显身手的时候了。

(2)责任链模式定义

责任链模式(Chain of Responsibility  Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

a.优点

请求的发送者和接收者(请求的处理)解耦。

责任链可以动态组合。可以消除大部分if...else的判断。

b.缺点

链太长的话,影响性能。如果链上的多个节点中,只有一个有资格处理某个对象的请求,但是需要沿着链一个一个往后流转,直至流转到可以处理当前对象请求的的节点那里。 这就像数组和链表的取值区别一样,取数组下标为4的数可以直接取,但取链表的第几个节点的值时,xu

2、代码

(1)场景

假如一个课程由视频和文章笔记组成,每次发布提交,都需要专门有人进行审核把关,只有在层层把关通过后,才可以顺利上线。

这里我们构建一个(抽象类)审批者Approver,不同方面不同层次的审核都通过继承该抽象类进行具体定义。

同时,关键要指定下一层审批类。即每个审批类不仅要实现具体某个方面的审批校验,同时还要指定下一个审批者是谁,下一棒交到谁手里。就像链表,每个节点不仅要保存数据,还必须要指定下一个节点是哪个,最终才能形成完整的链条

(2)类图

(3)关键的类

全部代码可以在这里:

https://github.com/phs999/DesignPatterns/tree/cad1abd66509458bef3c1603974582cd0839ee22/design_pattern/src/behavioral/chainofresponsibility

package behavioral.chainofresponsibility;
//批准者
public abstract class Approver {

	protected Approver approver;
	
	public void setNextApprover(Approver approver) {
		this.approver=approver;
	}
	
	//发布课程
	public abstract void deploy(Course course);
	
}
package behavioral.chainofresponsibility;

public class AticleApprover extends Approver{

	@Override
	public void deploy(Course course) {

		if (course.getArticle()!=null&&!course.getArticle().equals("")) {
			System.out.println(course.getName()+"含有文章手记,内容正常,批准");
			if (approver!=null) {
				approver.deploy(course);
			}
		}else {
			System.out.println(course.getName()+"不含有文章手记或内容不正常,不批准,流程结束");
			return;
		}
	}

}
package behavioral.chainofresponsibility;

public class VideoApprover extends Approver{

	@Override
	public void deploy(Course course) {

		if (course.getVideo()!=null&&!course.getVideo().equals("")) {
			System.out.println(course.getName()+"含有视频,内容正常,批准");
			if (approver!=null) {
				approver.deploy(course);
			}
		}else {
			System.out.println(course.getName()+"不含有视频或内容不正常,不批准,流程结束");
			return;
		}
	}

}

最后是在Test类中,指定了审批类之间的关联关系,即先通过谁审批,再通过谁审批。

package behavioral.chainofresponsibility;

public class Test {
	public static void main(String[] args) {
		Approver articleApprover=new AticleApprover();
		Approver videoApprover=new VideoApprover();
		Course course=new Course();
		course.setName("XX课程");
		course.setArticle("详细手记文章");
		course.setVideo("详细视频讲解");
		
		articleApprover.setNextApprover(videoApprover);
		articleApprover.deploy(course);
	}
}

 

3、项目源码

一般我们在项目源码中看到诸如XXXChain,XXXHandler的时候,一般我们就可以往责任链模式上靠了。是不是有一个统一的抽象类或接口,是不是每个子类分别实现了不同的校验,并且还定义了下一个要流向的子类。

比如,在sevlet包中,有一个叫FilterChain的接口,它定义了对于请求的过滤方法。而其实现类比如MockFilterChain类,则集合了众多的Filter过滤器,同时定义了过滤器使用的流向。Filter本身是个接口,有众多实现类。


坦克大战代码中对于责任链模式的应用介绍在这里:

https://blog.csdn.net/phs999/article/details/107453246

 

参考:https://blog.csdn.net/LoveLion/article/details/7420893 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值