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