Сеть Apache Commons
1. Вступление
Apache Commons Chain - это библиотека, которая использует цепочку ответственностиpattern - обычно используется для организации сложных потоков обработки, в которых несколько получателей могут обрабатывать запрос.
В этой быстрой статье мы рассмотрим пример вывода средств из банкомата.
2. Maven Dependency
Для начала импортируем последнюю версию этой библиотеки с помощью Maven:
commons-chain
commons-chain
1.2
Чтобы проверить наличие самой последней версии этой библиотеки -go here.
3. Пример цепочки
Банкомат принимает число в качестве ввода и передает его обработчикам, ответственным за выполнение различных действий. Они включают в себя подсчет количества банкнот, подлежащих выдаче, и отправку уведомления банку и клиенту о транзакции.
4. Цепной контекст
Контекст представляет текущее состояние приложения, хранящего информацию о транзакции.
Для запроса на снятие средств через банкомат нам нужна следующая информация:
-
Общая сумма для снятия
-
Количество банкнот номиналом 100
-
Количество наименований номиналом 50
-
Количество наименований номиналом 10
-
Сумма, оставленная для снятия
Это состояние определяется в классе:
public class AtmRequestContext extends ContextBase {
int totalAmountToBeWithdrawn;
int noOfHundredsDispensed;
int noOfFiftiesDispensed;
int noOfTensDispensed;
int amountLeftToBeWithdrawn;
// standard setters & getters
}
5. команда
Command принимаетContext в качестве входных данных и обрабатывает его.
Мы реализуем каждый из шагов, упомянутых выше, как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;
}
}
Commands дляFiftyDenominationDispenser &TenDenominationDispenser аналогичны.
6. цепь
Chain - это набор команд, которые должны выполняться в указанном порядке. НашChain будет состоять из указанного вышеCommands, а такжеAuditFilter в конце:
public class AtmWithdrawalChain extends ChainBase {
public AtmWithdrawalChain() {
super();
addCommand(new HundredDenominationDispenser());
addCommand(new FiftyDenominationDispenser());
addCommand(new TenDenominationDispenser());
addCommand(new AuditFilter());
}
}
Когда любойCommand вChain возвращает истину, он принудительно завершаетChain.
7. Фильтр
Фильтр также являетсяCommand, но с методомpostProcess, который вызывается после выполненияChain.
Наш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. Каталог цепей
Это наборChains иCommands с их логическими именами.
В нашем случае нашCatalog будет содержатьAtmWithdrawalChain.
public class AtmCatalog extends CatalogBase {
public AtmCatalog() {
super();
addCommand("atmWithdrawalChain", new AtmWithdrawalChain());
}
}
9. Использование цепи
Давайте посмотрим, как мы можем использовать указанные вышеChain для обработки запроса на снятие средств. Сначала мы создадимContext, а затем передадим емуChain..Chain обработаетContext.
Мы напишем тестовый пример, чтобы продемонстрировать наш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. Заключение
В этом руководстве мы изучили практический сценарий с использованием библиотеки Apache Commons Chain от Apache, о которой вы можете узнать больше оhere.
И, как всегда, доступен код для этой статьиover on Github.