Welcome to follow the official wechat account: FSA Full stack action 👋

I. Introduction of responsibility chain model

In the Chain of Responsibility Pattern, when a client sends a request, all the objects in the Chain have the opportunity to process the request, and the client does not need to know who the specific processing object is, so that multiple objects have the opportunity to process the request, avoiding the coupling relationship between the sender and receiver of the request. The object is concatenated into a chain of calls and the request is passed along the chain until an object processes it.

There are two core behaviors: one is to process the request, and the other is to pass the request to the next node

  • The core of

    • Handler Abstract Handler: Defines an interface to process a request
    • ConcreteHandler handler: Handles the responsible request, accessing its subsequent nodes, if it can handle the request, or forwarding it to its subsequent nodes otherwise
  • Application scenarios

    • SprintBoot interceptor, filter chain
    • Request interceptor in Okhttp
    • Submit a request to one of multiple objects without specifying the request handler
    • If you have multiple objects that can handle the same request, but which object to handle is dynamically determined by the runtime, you can use the chain of responsibilities pattern
  • advantages

    • The customer only needs to send the request to the responsibility chain, and does not need to care about the processing details of the request and the transmission of the request, so the responsibility chain reduces the coupling degree between the sender of the request and the handler of the request
    • By changing the order in which they are transferred within the chain, processing classes can be dynamically added or removed for easier maintenance
    • The expansibility of the system is enhanced, and new request processing classes can be added according to the needs to meet the open and closed principle
    • Each class only needs to handle its own work, clearly define the scope of responsibility, and meet the single responsibility principle
  • disadvantages

    • The processing is dispersed into separate responsibility objects, each of which has a single function. To process the whole process, many responsibility objects are needed, resulting in a large number of fine-grained responsibility objects
    • It is not guaranteed that the request will be received. If the link is long, the system performance will be affected, and it is not convenient for code scheduling

Second, responsibility chain model code implementation

Take the risk control of Alipay transfer as an example. According to the amount of transfer, different risk control levels will be triggered. Direct transfer is required for less than 1,000 yuan. The following uses the chain of responsibility pattern to achieve these three risk control treatments:

Create account request class:

/** * Transfer request **@author GitLqr
 */
public class TransferRequest {

	/ / the amount
	private int money;

	public TransferRequest(int money) {
		super(a);this.money = money;
	}

	public int getMoney(a) {
		return money;
	}

	public void setMoney(int money) {
		this.money = money; }}Copy the code

Create abstract handler:

Description: Defines a processing method that all handlers must implement, and also needs to hold a reference to the next handler

/** * Abstract handler: Risk control abstract class **@author GitLqr
 */
public abstract class AbstractRiskControlHandler {

	// Name of the current risk control handler
	protected String name;
	// The next level of risk control handler
	protected AbstractRiskControlHandler superior;

	public AbstractRiskControlHandler(String name) {
		super(a);this.name = name;
	}

	/** ** Process transfer requests */
	public abstract void handleRequest(TransferRequest transferRequest);

	public AbstractRiskControlHandler getSuperior(a) {
		return superior;
	}

	public void setSuperior(AbstractRiskControlHandler superior) {
		this.superior = superior; }}Copy the code

Create concrete handler:

/** * Handler: Primary risk control handler **@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("For common operation, enter the payment password.");
			System.out.println(name + ", transfer amount:" + transferRequest.getMoney() + "Processing completed");
		} else {
			// Proceed to the next node
			if(superior ! =null) { superior.handleRequest(transferRequest); }}}}/** * Handler: Intermediate risk control handler **@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("For a slightly larger operation, input payment password + SMS verification code.");
			System.out.println(name + ", transfer amount:" + transferRequest.getMoney() + "Processing completed");
		} else {
			// Proceed to the next node
			if(superior ! =null) { superior.handleRequest(transferRequest); }}}}/** * Handler: Advanced risk control handler **@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("For large operation, input payment password + SMS verification code + face recognition");
			System.out.println(name + ", transfer amount:" + transferRequest.getMoney() + "Processing completed");
		} else {
			// Proceed to the next node
			if(superior ! =null) { superior.handleRequest(transferRequest); }}}}Copy the code

Use:

public static void main(String[] args) {
    AbstractRiskControlHandler firstControlHandler = new FirstRiskControlHandler("Primary Risk control");
    AbstractRiskControlHandler secondControlHandler = new SecondRiskControlHandler("Intermediate risk control");
    AbstractRiskControlHandler thirdControlHandler = new ThirdRiskControlHandler("Advanced Risk Control");

    // Form the call chain
    firstControlHandler.setSuperior(secondControlHandler);
    secondControlHandler.setSuperior(thirdControlHandler);

    TransferRequest request = new TransferRequest(1000); / / 1600, 20000
    firstControlHandler.handleRequest(request);
}
Copy the code

If this article is helpful to you, please click on my wechat official number: FSA Full Stack Action, which will be the biggest incentive for me. The public account not only has Android technology, but also iOS, Python and other articles, which may have some skills you want to know about oh ~