-5

Java 8 で Lambda を使用して Chain of Responsibility パターンをどのように実装しますか?


この記事には次の段落しか見つかりませんでした。

責任の連鎖

別のラムダにデリゲートする場合としない場合があるラムダ、別のラムダにデリゲートする場合としない場合があるラムダ、無限。(ラムダへの「次の」参照を取得する方法は、読者の演習として残されています。)

4

1 に答える 1

13

ウィキペディアの記事からJavaの例を採用しました:

この例では、さまざまな役割があり、それぞれに固定の購入制限と後継者がいます。ロール内のユーザーが制限を超える購入リクエストを受信するたびに、そのリクエストは後継者に渡されます。

ビルダーは、ハンドラのチェーンを構築することを許可します:

public class Main {
    public static void main(String[] args) {
        final double base = 500;
        ChainBuilder<PurchaseRequest> chainBuilder = ChainBuilder.chainBuilder();
        Chain<PurchaseRequest> chain = chainBuilder
                .first(request -> {
                    if (request.getAmount() < base * 10) {
                        System.out.println("Manager will approve $" + request.getAmount());
                        return true;
                    }
                    return false;
                })
                .successor(request -> {
                    if (request.getAmount() < base * 20) {
                        System.out.println("Director will approve $" + request.getAmount());
                        return true;
                    }
                    return false;
                })
                .successor(request -> {
                    if (request.getAmount() < base * 50) {
                        System.out.println("President will approve $" + request.getAmount());
                    } else {
                        System.out.println("Your request for $" + request.getAmount() + " needs a board meeting!");
                    }
                    return true;
                }).build();

        chain.handle(new PurchaseRequest(1000)); // manager
        chain.handle(new PurchaseRequest(9000)); // director
        chain.handle(new PurchaseRequest(23000)); // president
        chain.handle(new PurchaseRequest(100000)); // board
    }

    private static class PurchaseRequest {
        private final double amount;

        private PurchaseRequest(double amount) {
            this.amount = amount;
        }

        public double getAmount() {
            return amount;
        }
    }
}

ラムダは機能インターフェースを実装しますHandler。リクエストが処理された場合、リクエストが後続者によって処理される必要がある場合は、次trueのように返されます。false

public interface Handler<T> {
    boolean handle(T t);
}

これChainは、コンシューマーに似た基本的なインターフェイスです。

public interface Chain<T> {
    void handle(T t);
}

ビルダーの実装:

package com.intactile.vega.api;

public class ChainBuilder<T> {
    public static <T> ChainBuilder<T> chainBuilder() {
        return new ChainBuilder<>();
    }

    private HandlerImpl<T> first;

    private ChainBuilder() {
    }

    public SuccessorBuilder first(Handler<T> handler) {
        first = new HandlerImpl<>(handler);
        return new SuccessorBuilder(first);
    }

    public class SuccessorBuilder {
        private HandlerImpl<T> current;

        private SuccessorBuilder(HandlerImpl<T> current) {
            this.current = current;
        }

        public SuccessorBuilder successor(Handler<T> successor) {
            HandlerImpl<T> successorWrapper = new HandlerImpl<>(successor);
            current.setSuccessor(successorWrapper);
            current = successorWrapper;
            return this;
        }

        public Chain<T> build() {
            return new ChainImpl<T>(first);
        }
    }

    private static class ChainImpl<T> implements Chain<T> {
        private final Handler<T> first;

        public ChainImpl(Handler<T> first) {
            this.first = first;
        }

        @Override
        public void handle(T t) {
            first.handle(t);
        }
    }

    private static class HandlerImpl<T> implements Handler<T> {
        private final Handler<T> delegate;
        private Handler<T> successor;

        public HandlerImpl(Handler<T> delegate) {
            this.delegate = delegate;
        }

        private void setSuccessor(HandlerImpl<T> successor) {
            this.successor = successor;
        }

        @Override
        public boolean handle(T t) {
            if (delegate.handle(t)) {
                return true;
            }
            else if (successor != null) {
                return successor.handle(t);
            }
            return false;
        }
    }
}
于 2016-04-08T09:13:44.607 に答える