1. Introduction
1.介绍
Apache Commons Chain is a library that uses the Chain of Responsibility pattern – generally used for organizing complex processing flows in which multiple receivers can process a request.
Apache Commons Chain是一个使用责任链模式的库–一般用于组织复杂的处理流程,其中多个接收者可以处理一个请求。
In this quick article, we’ll go through an example representing a withdrawal from an ATM.
在这篇快速文章中,我们将通过一个代表从自动取款机提款的例子。
2. Maven Dependency
2.Maven的依赖性
To start, we’ll import the latest version of this library using Maven:
首先,我们要用Maven导入这个库的最新版本。
<dependency>
<groupId>commons-chain</groupId>
<artifactId>commons-chain</artifactId>
<version>1.2</version>
</dependency>
To check for the most recent version of this library – go here.
要检查这个库的最新版本 – 到这里。
3. Example Chain
3.实例链
The ATM takes a number as an input and passes it down to handlers responsible for performing different actions. Those involve calculating numbers of bank notes to be dispensed, and sending a notification to the bank and customer about the transaction.
自动取款机将一个数字作为输入,并将其传递给负责执行不同行动的处理程序。这些动作包括计算要发放的纸币数量,并向银行和客户发送有关交易的通知。
4. Chain Context
4.产业链背景
The context represents the current state of an application, storing information about the transaction.
上下文代表了一个应用程序的当前状态,存储了关于交易的信息。
For our ATM withdrawal request, the information we need is:
对于我们的ATM提款请求,我们需要的信息是。
- Total amount to be withdrawn
- Number of 100 denomination notes
- Number of 50 denomination notes
- Number of 10 denomination notes
- Amount left to be withdrawn
This state is defined in a class:
这种状态被定义在一个类中。
public class AtmRequestContext extends ContextBase {
int totalAmountToBeWithdrawn;
int noOfHundredsDispensed;
int noOfFiftiesDispensed;
int noOfTensDispensed;
int amountLeftToBeWithdrawn;
// standard setters & getters
}
5. Command
5 指挥
The Command takes the Context as an input and processes it.
命令将Context作为输入并处理。
We’ll implement each of the steps mentioned above as a Command:
我们将把上面提到的每个步骤作为一个命令来实现:。
public class HundredDenominationDispenser implements Command {
@Override
public boolean execute(Context context) throws Exception {
intamountLeftToBeWithdrawn = (int) context.get("amountLeftToBeWithdrawn);
if (amountLeftToBeWithdrawn >= 100) {
context.put("noOfHundredsDispensed", amountLeftToBeWithdrawn / 100);
context.put("amountLeftToBeWithdrawn", amountLeftToBeWithdrawn % 100);
}
return false;
}
}
The Commands for FiftyDenominationDispenser & TenDenominationDispenser are similar.
FiftyDenominationDispenser和TenDenominationDispenser的Commands是类似的。
6. Chain
6.链条
A Chain is a collection of commands to be executed in a specified order. Our Chain will consist of the above Commands and also an AuditFilter at the end:
一个链是按指定顺序执行的命令的集合。我们的链将由上述Commands和最后的AuditFilter组成。
public class AtmWithdrawalChain extends ChainBase {
public AtmWithdrawalChain() {
super();
addCommand(new HundredDenominationDispenser());
addCommand(new FiftyDenominationDispenser());
addCommand(new TenDenominationDispenser());
addCommand(new AuditFilter());
}
}
When any Command in the Chain returns true, it forces the Chain to end.
当链中的任何命令返回true时,它迫使链结束。
7. Filter
7.滤波器
A filter is also a Command but with a postProcess method that is called after the execution of the Chain.
过滤器也是一个命令,但是有一个postProcess方法,在执行链之后被调用。
Our Filter will send a notification to the customer & the bank:
我们的Filter将向客户和银行发送通知。
public class AuditFilter implements Filter {
@Override
public boolean postprocess(Context context, Exception exception) {
// send notification to bank and user
return false;
}
@Override
public boolean execute(Context context) throws Exception {
return false;
}
}
8. Chain Catalog
8.连锁店目录
It is a collection of Chains and Commands with their logical names.
它是一个带有逻辑名称的链和命令的集合。
In our case, our Catalog will contain the AtmWithdrawalChain.
在我们的案例中,我们的目录将包含AtmWithdrawalChain.。
public class AtmCatalog extends CatalogBase {
public AtmCatalog() {
super();
addCommand("atmWithdrawalChain", new AtmWithdrawalChain());
}
}
9. Using the Chain
9.使用链条
Let’s see how we can use the above Chain to process a withdrawal request. We’ll first create a Context and then pass it the Chain. The Chain will process the Context.
让我们看看我们如何使用上述Chain来处理一个提款请求。我们将首先创建一个Context,然后将Chain传递给它。Chain将处理Context。链将处理上下文。
We’ll write a test case to demonstrate our AtmWithdrawalChain:
我们将写一个测试案例来演示我们的AtmWithdrawalChain:。
public class AtmChainTest {
@Test
public void givenInputsToContext_whenAppliedChain_thenExpectedContext() throws Exception {
Context context = new AtmRequestContext();
context.put("totalAmountToBeWithdrawn", 460);
context.put("amountLeftToBeWithdrawn", 460);
Catalog catalog = new AtmCatalog();
Command atmWithdrawalChain = catalog.getCommand("atmWithdrawalChain");
atmWithdrawalChain.execute(context);
assertEquals(460, (int) context.get("totalAmountToBeWithdrawn"));
assertEquals(0, (int) context.get("amountLeftToBeWithdrawn"));
assertEquals(4, (int) context.get("noOfHundredsDispensed"));
assertEquals(1, (int) context.get("noOfFiftiesDispensed"));
assertEquals(1, (int) context.get("noOfTensDispensed"));
}
}
10. Conclusion
10.结论
In this tutorial, we explored a practical scenario using the Apache’s Apache Commons Chain library – which you can read more about here.
在本教程中,我们使用Apache的Apache Commons Chain库探索了一个实际场景–你可以在这里阅读更多关于Apache Commons Chain库的信息。
And, as always, the code for this article is available over on Github.
而且,像往常一样,这篇文章的代码可以在Github上找到。