Apache Commons Chain

1. Въведение

Apache Commons Chain е библиотека, която използва модела Chain of Responsibility - обикновено се използва за организиране на сложни процеси на обработка, в които множество получатели могат да обработват заявка.

В тази бърза статия ще разгледаме пример, представляващ теглене от банкомат.

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 Контекст като вход и да го обработва.

Ще изпълним всяка от стъпките, споменати по-горе като команда:

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 Command ите за FiftyDenominationDispenser & TenDenominationDispenser са сходни.

6. Верига

А верига е съвкупност от команди, за да бъде изпълнена в определен ред. Нашата верига ще се състои от горните команди, а също и AuditFilter в края:

public class AtmWithdrawalChain extends ChainBase { public AtmWithdrawalChain() { super(); addCommand(new HundredDenominationDispenser()); addCommand(new FiftyDenominationDispenser()); addCommand(new TenDenominationDispenser()); addCommand(new AuditFilter()); } }

Когато някоя от командите във веригата върне вярно, тя принуждава веригата да приключи.

7. Филтър

Филтърът също е команда, но с метод postProcess , който се извиква след изпълнението на веригата.

Нашият филтър ще изпрати известие до клиента и банката:

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. Верижен каталог

Това е колекция от вериги и команди с техните логически имена.

В нашия случай нашият каталог ще съдържа AtmWithdrawalChain.

public class AtmCatalog extends CatalogBase { public AtmCatalog() { super(); addCommand("atmWithdrawalChain", new AtmWithdrawalChain()); } }

9. Използване на веригата

Нека да видим как можем да използваме горната верига за обработка на заявка за теглене. Първо ще създадем контекст и след това ще му предадем веригата. Най- верига ще обработи контекст.

Ще напишем тестов случай, за да покажем нашата 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 - за който можете да прочетете повече тук.

И както винаги, кодът за тази статия е достъпен в Github.