当前位置: 首页 > 工具软件 > Java dollar > 使用案例 >

java责任链设计模式_Java中的责任链设计模式

穆鸿飞
2023-12-01

java责任链设计模式

Chain of responsibility design pattern is one of the behavioral design pattern.

责任链设计模式是行为设计模式之一

责任链设计模式 (Chain of Responsibility Design Pattern)

Chain of responsibility pattern is used to achieve loose coupling in software design where a request from client is passed to a chain of objects to process them. Then the object in the chain will decide themselves who will be processing the request and whether the request is required to be sent to the next object in the chain or not.

责任链模式用于实现软件设计中的松散耦合,其中将来自客户端的请求传递到对象链以对其进行处理。 然后,链中的对象将自行决定将由谁处理请求,以及是否需要将请求发送到链中的下一个对象。

JDK中的责任链模式示例 (Chain of Responsibility Pattern Example in JDK)

Let’s see the example of chain of responsibility pattern in JDK and then we will proceed to implement a real life example of this pattern. We know that we can have multiple catch blocks in a try-catch block code. Here every catch block is kind of a processor to process that particular exception.

让我们看一下JDK中的责任链模式的示例,然后我们将继续实现这种模式的真实示例。 我们知道在try-catch块代码中可以有多个catch块。 在这里,每个catch块都是一种处理器,用于处理该特定异常。

So when any exception occurs in the try block, its send to the first catch block to process. If the catch block is not able to process it, it forwards the request to next object in chain i.e next catch block. If even the last catch block is not able to process it, the exception is thrown outside of the chain to the calling program.

因此,当try块中发生任何异常时,它将发送到第一个catch块进行处理。 如果catch块无法处理它,则将请求转发到链中的下一个对象,即next catch块。 如果即使最后一个catch块也无法处理它,则将异常抛出到调用程序的链外。

责任链设计模式示例 (Chain of Responsibility Design Pattern Example)

One of the great example of Chain of Responsibility pattern is ATM Dispense machine. The user enters the amount to be dispensed and the machine dispense amount in terms of defined currency bills such as 50$, 20$, 10$ etc.

ATM分配机是“责任链”模式的一个很好的例子。 用户输入要分配的金额,并根据已定义的货币票据(例如50 $,20 $,10 $等)输入机器分配的金额。

If the user enters an amount that is not multiples of 10, it throws error. We will use Chain of Responsibility pattern to implement this solution. The chain will process the request in the same order as below image.

如果用户输入的金额不是10的倍数,则会引发错误。 我们将使用责任链模式来实现此解决方案。 链将按照下图相同的顺序处理请求。

Note that we can implement this solution easily in a single program itself but then the complexity will increase and the solution will be tightly coupled. So we will create a chain of dispense systems to dispense bills of 50$, 20$ and 10$.

请注意,我们可以在单个程序本身中轻松实现此解决方案,但是复杂性将增加,并且解决方案将紧密耦合。 因此,我们将创建一个分配系统链,以分配50美元,20美元和10美元的钞票。

责任链设计模式–基类和接口 (Chain of Responsibility Design Pattern – Base Classes and Interface)

We can create a class Currency that will store the amount to dispense and used by the chain implementations.

我们可以创建一个Currency类,该类将存储要分配的金额并供链实现使用。

Currency.java

Currency.java

package com.journaldev.design.chainofresponsibility;

public class Currency {

	private int amount;
	
	public Currency(int amt){
		this.amount=amt;
	}
	
	public int getAmount(){
		return this.amount;
	}
}

The base interface should have a method to define the next processor in the chain and the method that will process the request. Our ATM Dispense interface will look like below.

基本接口应具有定义链中下一个处理器的方法以及将处理请求的方法。 我们的ATM分配界面如下所示。

DispenseChain.java

DispenseChain.java

package com.journaldev.design.chainofresponsibility;

public interface DispenseChain {

	void setNextChain(DispenseChain nextChain);
	
	void dispense(Currency cur);
}

责任链模式–链实施 (Chain of Responsibilities Pattern – Chain Implementations)

We need to create different processor classes that will implement the DispenseChain interface and provide implementation of dispense methods. Since we are developing our system to work with three types of currency bills – 50$, 20$ and 10$, we will create three concrete implementations.

我们需要创建不同的处理器类,以实现DispenseChain接口并提供DispenseChain方法的实现。 由于我们正在开发可与三种类型的货币票据(50美元,20美元和10美元)一起使用的系统,因此我们将创建三个具体的实现。

Dollar50Dispenser.java

Dollar50Dispenser.java

package com.journaldev.design.chainofresponsibility;

public class Dollar50Dispenser implements DispenseChain {

	private DispenseChain chain;
	
	@Override
	public void setNextChain(DispenseChain nextChain) {
		this.chain=nextChain;
	}

	@Override
	public void dispense(Currency cur) {
		if(cur.getAmount() >= 50){
			int num = cur.getAmount()/50;
			int remainder = cur.getAmount() % 50;
			System.out.println("Dispensing "+num+" 50$ note");
			if(remainder !=0) this.chain.dispense(new Currency(remainder));
		}else{
			this.chain.dispense(cur);
		}
	}

}

Dollar20Dispenser.java

Dollar20Dispenser.java

package com.journaldev.design.chainofresponsibility;

public class Dollar20Dispenser implements DispenseChain{

	private DispenseChain chain;
	
	@Override
	public void setNextChain(DispenseChain nextChain) {
		this.chain=nextChain;
	}

	@Override
	public void dispense(Currency cur) {
		if(cur.getAmount() >= 20){
			int num = cur.getAmount()/20;
			int remainder = cur.getAmount() % 20;
			System.out.println("Dispensing "+num+" 20$ note");
			if(remainder !=0) this.chain.dispense(new Currency(remainder));
		}else{
			this.chain.dispense(cur);
		}
	}

}

Dollar10Dispenser.java

Dollar10Dispenser.java

package com.journaldev.design.chainofresponsibility;

public class Dollar10Dispenser implements DispenseChain {

	private DispenseChain chain;
	
	@Override
	public void setNextChain(DispenseChain nextChain) {
		this.chain=nextChain;
	}

	@Override
	public void dispense(Currency cur) {
		if(cur.getAmount() >= 10){
			int num = cur.getAmount()/10;
			int remainder = cur.getAmount() % 10;
			System.out.println("Dispensing "+num+" 10$ note");
			if(remainder !=0) this.chain.dispense(new Currency(remainder));
		}else{
			this.chain.dispense(cur);
		}
	}

}

The important point to note here is the implementation of dispense method. You will notice that every implementation is trying to process the request and based on the amount, it might process some or full part of it.

这里要注意的重要一点是分配方法的实现。 您会注意到,每个实现都尝试处理该请求,并且根据数量,它可能会处理部分或全部请求。

If one of the chain not able to process it fully, it sends the request to the next processor in chain to process the remaining request. If the processor is not able to process anything, it just forwards the same request to the next chain.

如果链中的一个不能完全处理它,它将请求发送到链中的下一个处理器以处理剩余的请求。 如果处理器无法处理任何内容,它只会将相同的请求转发到下一个链。

责任链设计模式–创建链 (Chain of Responsibilities Design Pattern – Creating the Chain)

This is a very important step and we should create the chain carefully, otherwise a processor might not be getting any request at all. For example, in our implementation if we keep the first processor chain as Dollar10Dispenser and then Dollar20Dispenser, then the request will never be forwarded to the second processor and the chain will become useless.

这是非常重要的一步,我们应该仔细创建链,否则处理器可能根本不会收到任何请求。 例如,在我们的实现,如果我们坚持前处理器链Dollar10Dispenser然后Dollar20Dispenser ,那么请求将不会被转发到第二处理器和链将变得毫无用处。

Here is our ATM Dispenser implementation to process the user requested amount.

这是我们的ATM自动提款机实施方案,用于处理用户请求的金额。

ATMDispenseChain.java

ATMDispenseChain.java

package com.journaldev.design.chainofresponsibility;

import java.util.Scanner;

public class ATMDispenseChain {

	private DispenseChain c1;

	public ATMDispenseChain() {
		// initialize the chain
		this.c1 = new Dollar50Dispenser();
		DispenseChain c2 = new Dollar20Dispenser();
		DispenseChain c3 = new Dollar10Dispenser();

		// set the chain of responsibility
		c1.setNextChain(c2);
		c2.setNextChain(c3);
	}

	public static void main(String[] args) {
		ATMDispenseChain atmDispenser = new ATMDispenseChain();
		while (true) {
			int amount = 0;
			System.out.println("Enter amount to dispense");
			Scanner input = new Scanner(System.in);
			amount = input.nextInt();
			if (amount % 10 != 0) {
				System.out.println("Amount should be in multiple of 10s.");
				return;
			}
			// process the request
			atmDispenser.c1.dispense(new Currency(amount));
		}

	}

}

When we run above application, we get output like below.

当我们在应用程序上方运行时,我们将得到如下输出。

Enter amount to dispense
530
Dispensing 10 50$ note
Dispensing 1 20$ note
Dispensing 1 10$ note
Enter amount to dispense
100
Dispensing 2 50$ note
Enter amount to dispense
120
Dispensing 2 50$ note
Dispensing 1 20$ note
Enter amount to dispense
15
Amount should be in multiple of 10s.

责任链设计模式类图 (Chain of Responsibilities Design Pattern Class Diagram)

Our ATM dispense example of chain of responsibility design pattern implementation looks like below image.

我们的ATM责任链设计模式实现的分配示例如下图所示。

责任链设计模式要点 (Chain of Responsibility Design Pattern Important Points)

  • Client doesn’t know which part of the chain will be processing the request and it will send the request to the first object in the chain. For example, in our program ATMDispenseChain is unaware of who is processing the request to dispense the entered amount.

    客户不知道链中的哪一部分将处理请求,它将把请求发送到链中的第一个对象。 例如,在我们的程序中,ATMDispenseChain不知道是谁在处理分配输入金额的请求。
  • Each object in the chain will have it’s own implementation to process the request, either full or partial or to send it to the next object in the chain.

    链中的每个对象都有其自己的实现来处理请求(全部或部分请求)或将其发送到链中的下一个对象。
  • Every object in the chain should have reference to the next object in chain to forward the request to, its achieved by java composition.

    链中的每个对象都应引用链中的下一个对象,以将请求转发给它,此请求由java组成
  • Creating the chain carefully is very important otherwise there might be a case that the request will never be forwarded to a particular processor or there are no objects in the chain who are able to handle the request. In my implementation, I have added the check for the user entered amount to make sure it gets processed fully by all the processors but we might not check it and throw exception if the request reaches the last object and there are no further objects in the chain to forward the request to. This is a design decision.

    仔细创建链非常重要,否则可能会导致请求永远不会转发到特定处理器,或者链中没有能够处理该请求的对象。 在我的实现中,我添加了对用户输入金额的检查,以确保所有处理器都对它进行了完全处理,但是如果请求到达最后一个对象并且链中没有其他对象,我们可能不会检查并抛出异常将请求转发给。 这是设计决定。
  • Chain of Responsibility design pattern is good to achieve lose coupling but it comes with the trade-off of having a lot of implementation classes and maintenance problems if most of the code is common in all the implementations.

    责任链设计模式可以很好地实现失去耦合,但是如果大多数代码在所有实现中都是通用的,那么它就有许多实现类和维护问题的权衡。

JDK中的责任链模式示例 (Chain of Responsibility Pattern Examples in JDK)

  • java.util.logging.Logger#log()

    java.util.logging.Logger#log()
  • javax.servlet.Filter#doFilter()

    javax.servlet.Filter#doFilter()

Thats all for the Chain of Responsibility design pattern, I hope you liked it and its able to clear your understanding on this design pattern.

以上就是“责任链”设计模式,我希望您喜欢它,并且它能够清除您对这种设计模式的理解。

翻译自: https://www.journaldev.com/1617/chain-of-responsibility-design-pattern-in-java

java责任链设计模式

 类似资料: