责任链 - lambda函数实现

时间:2016-04-07 18:33:22

标签: java design-patterns lambda java-8 chain-of-responsibility

如何在Java 8中使用Lambda实现Chain of Responsibility模式?它看起来怎么样?

我只在this article中找到了一个段落:

  

责任链

     

一个可能会或可能不会委托给另一个lambda的lambda,它可能会或可能不会委托给另一个lambda,无限制。   (如何将“下一个”引用到lambda中作为练习留给读者。)

1 个答案:

答案 0 :(得分:7)

我改编了_add_items

  

在这个例子中,我们有不同的角色,每个角色都有一个固定的购买限制和一个后继者。每当角色中的用户收到超出其限额的购买请求时,请求都会传递给他或她的继任者。

构建器允许构建处理程序链:

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

lambda实现了功能接口Handler。如果处理了请求,则返回truefalse如果请求应由后继处理者处理:

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