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>

このライブラリの最新版を確認するには –

https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22commons-chain%22%20AND%20a%3A%22commons-chain%

22[ここへ]


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に追加]から入手できます。