Apache Commons Chain

1前書き

Apache Commons Chain は、Chain of Responsibility pattern を使用したライブラリです。 - 一般に、複数の受信者が要求を処理できる複雑な処理フローを編成するために使用されます。

このクイック記事では、ATMからの引き出しを表す例を紹介します。

2 Mavenの依存関係

まず、Mavenを使ってこのライブラリの最新版をインポートします。

<dependency>
    <groupId>commons-chain</groupId>
    <artifactId>commons-chain</artifactId>
    <version>1.2</version>
</dependency>

3チェーン例

ATMは入力として数値を取り、それをさまざまなアクションの実行を担当するハンドラーに渡します。それらは、分配されるべき紙幣の数を計算すること、および取引について銀行および顧客に通知を送ることを含む。

4チェーンコンテキスト

コンテキストはアプリケーションの現在の状態を表し、トランザクションに関する情報を格納します。

私たちのATM引き出し要求のために、私たちが必要とする情報は次のとおりです。

  • お引き落とし金額

  • 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;
    }
}

FiftyDenominationDispenser __Command __s

6. 鎖

Chain は、指定された順序で実行されるコマンドの集まりです。私たちの Chain は上記の __Command sと最後にある AuditFilter__で構成されます。

public class AtmWithdrawalChain extends ChainBase {

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

Chain 内のいずれかの Command がtrueを返すと、 Chain は強制的に終了します。

7. フィルタ

フィルタも Command ですが、 Chainの実行後に呼び出される postProcess__メソッドがあります。

私たちの 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のApache Commons Chainライブラリを使った実用的なシナリオを探りました。

そして、いつものように、この記事のコードはhttps://github.com/eugenp/tutorials/tree/master/libraries-apache-commons[Githubに追加]から入手できます。