DesignPattern - 责任链模式行为型

Posted GitLqr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DesignPattern - 责任链模式行为型相关的知识,希望对你有一定的参考价值。

欢迎关注微信公众号:FSA全栈行动 👋

一、责任链模式介绍

责任链模式(Chain of Responsibility Pattern)客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁具体的处理对象,让多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条调用链,并沿着这条链传递该请求,直到有一个对象处理它才终止。

2 个核心行为:一是处理请求,二是将请求传递到下一节点

  • 核心组成

    • Handler 抽象处理者:定义一个处理请求的接口
    • ConcreteHandler 具体处理者:处理所负责的请求,可访问它的后续节点,如果可处理该请求就处理,否则就将该请求转发给它的后续节点
  • 应用场景

    • SprintBoot 里的拦截器、过滤器链
    • Okhttp 里的请求拦截器
    • 在请求处理者不明确的情况下向多个对象中的一个提交请求
    • 如果有多个对象可以处理同一个请求,但是具体由哪个对象处理是由运行时动态决定的,这种对象就可以使用职责链模式
  • 优点

    • 客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递,所以责任链将请求的发送者和请求的处理者降低了耦合度
    • 通过改变链内的调动它们的次序,允许动态地新增或者删除处理类,比较方便维护
    • 增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则
    • 每个类只需要处理自己该处理的工作,明确各类的责任范围,满足单一职责原则
  • 缺点

    • 处理都分散到了单独的职责对象中,每个对象功能单一,要把整个流程处理完,需要很多的职责对象,会产生大量的细粒度职责对象
    • 不能保证请求一定被接收,如果链路比较长,系统性能将受到一定影响,而且在进行代码调度时不太方便

二、责任链模式代码实现

以支付宝转账风控为例,根据转账额度不同,会触发的风控级别不一样,1 千以下直接转,1 千到 1 万需要手机号验证码,1 万以上需要刷脸验证。下面使用责任链模式来实现这 3 种风控处理:

创建账号请求类:

/**
 * 转账请求
 *
 * @author GitLqr
 */
public class TransferRequest 

	// 金额
	private int money;

	public TransferRequest(int money) 
		super();
		this.money = money;
	

	public int getMoney() 
		return money;
	

	public void setMoney(int money) 
		this.money = money;
	

创建 抽象处理者:

说明:定义一个所有处理者必须实现的处理方法,还需要持有下个处理者的引用

/**
 * 抽象处理者:风控抽象类
 *
 * @author GitLqr
 */
public abstract class AbstractRiskControlHandler 

	// 当前风控处理器名称
	protected String name;
	// 下一级风控处理器
	protected AbstractRiskControlHandler superior;

	public AbstractRiskControlHandler(String name) 
		super();
		this.name = name;
	

	/**
	 * 处理转账请求
	 */
	public abstract void handleRequest(TransferRequest transferRequest);

	public AbstractRiskControlHandler getSuperior() 
		return superior;
	

	public void setSuperior(AbstractRiskControlHandler superior) 
		this.superior = superior;
	

创建 具体处理者:

/**
 * 具体处理者:初级风控处理器
 *
 * @author GitLqr
 */
public class FirstRiskControlHandler extends AbstractRiskControlHandler 

	public FirstRiskControlHandler(String name) 
		super(name);
	

	@Override
	public void handleRequest(TransferRequest transferRequest) 
		if (transferRequest.getMoney() <= 1000) 
			System.out.println("普通操作,输入支付密码即可");
			System.out.println(name + ",转账金额:" + transferRequest.getMoney() + " 处理完成");
		 else 
			// 下个节点进行处理
			if (superior != null) 
				superior.handleRequest(transferRequest);
			
		
	


/**
 * 具体处理者:中级风控处理器
 *
 * @author GitLqr
 */
public class SecondRiskControlHandler extends AbstractRiskControlHandler 

	public SecondRiskControlHandler(String name) 
		super(name);
	

	@Override
	public void handleRequest(TransferRequest transferRequest) 
		if (transferRequest.getMoney() > 1000 && transferRequest.getMoney() <= 10000) 
			System.out.println("稍大额操作,输入支付密码+短信验证码即可");
			System.out.println(name + ",转账金额:" + transferRequest.getMoney() + " 处理完成");
		 else 
			// 下个节点进行处理
			if (superior != null) 
				superior.handleRequest(transferRequest);
			
		
	


/**
 * 具体处理者:高级风控处理器
 *
 * @author GitLqr
 */
public class ThirdRiskControlHandler extends AbstractRiskControlHandler 

	public ThirdRiskControlHandler(String name) 
		super(name);
	

	@Override
	public void handleRequest(TransferRequest transferRequest) 
		if (transferRequest.getMoney() > 10000) 
			System.out.println("大额操作,输入支付密码+短信验证码+人脸识别");
			System.out.println(name + ",转账金额:" + transferRequest.getMoney() + " 处理完成");
		 else 
			// 下个节点进行处理
			if (superior != null) 
				superior.handleRequest(transferRequest);
			
		
	

使用:

public static void main(String[] args) 
    AbstractRiskControlHandler firstControlHandler = new FirstRiskControlHandler("初级风控");
    AbstractRiskControlHandler secondControlHandler = new SecondRiskControlHandler("中级风控");
    AbstractRiskControlHandler thirdControlHandler = new ThirdRiskControlHandler("高级风控");

    // 形成调用链
    firstControlHandler.setSuperior(secondControlHandler);
    secondControlHandler.setSuperior(thirdControlHandler);

    TransferRequest request = new TransferRequest(1000); // 1600, 20000
    firstControlHandler.handleRequest(request);

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有android技术, 还有ios, Python等文章, 可能有你想要了解的技能知识点哦~

以上是关于DesignPattern - 责任链模式行为型的主要内容,如果未能解决你的问题,请参考以下文章

DesignPattern - 责任链模式行为型

行为型模式:责任链模式

行为型设计模式之责任链模式

设计模式-命令模式(行为)责任链模式(行为)

5 行为型模式之- 责任链模式

责任链模式行为模式