2016-04-08 32 views
2

我遇到以下問題。我已經實現了流水線處理,有時我必須釋放資源,例如文件。同時,我的管道是異步的,所以它立即釋放控制權,我在Non-lamda實現中使用了關閉方法。我無法使用lambdas來插入它。我目前的代碼如下所示:PipeLine發佈資源lambda

@FunctionalInterface 
public interface Stage<T,Q> { 

    public Q process(T toProcess); 

} 


@FunctionalInterface 
public interface IntermediatStage<T,Q> extends Stage<T,Q> { 


    public default <P> IntermediatStage<T,P> nextStage(Stage<Q,P> nextStage) { 
     return (T t) -> {return nextStage.process(this.process(t)); }; 
    } 



} 

我需要隨後在不同階段調用關閉方法。問題是通過默認方法鏈接它們,我沒有對它們的可見性。當我添加階段的時候,是否有可能添加一個關閉鉤子,我可以稍後根據管道是異步的事實獨立調用?

謝謝

+2

也許你解決不了lambda表達式的一切。順便說一下,您的'Stage '與現有的'Function '接口沒有什麼不同...... – Holger

+1

IntermediateStage可以使用Function.andThen()' –

+0

來模擬IT不能,因爲andThen需要與功能。但在我的情況下,我需要函數和函數

回答

3

你只能用接口和lambda表達式解決所有問題。這看起來像一個簡單的任務具有這樣的模式和普通類:

public final class Stage<T,R> { 
    static final Runnable NO_OP =() -> {}; 
    public static <I,O> Stage<I,O> create(Function<I,O> f) { 
     return new Stage<>(f, NO_OP); 
    } 
    public static <I,O> Stage<I,O> create(Function<I,O> f, Runnable cleanup) { 
     return new Stage<>(f, cleanup); 
    } 
    private final Function<T,R> actualAction; 
    private final Runnable cleanup; 

    private Stage(Function<T,R> f, Runnable r) { 
     actualAction=f; 
     cleanup=r; 
    } 

    public <P> Stage<T,P> nextStage(Function<R,P> nextStage) { 
     return new Stage<>(actualAction.andThen(nextStage), cleanup); 
    } 
    public <P> Stage<T,P> nextStage(Function<R,P> nextStage, Runnable nextCleanup) { 
     return new Stage<>(actualAction.andThen(nextStage), 
      cleanup==NO_OP? nextCleanup:() -> { cleanup.run(); nextCleanup.run(); }); 
    } 
    public R process(T t) { 
     return actualAction.apply(t); 
    } 
    public Function<T, R> getActualAction() { 
     return actualAction; 
    } 
    public void cleanup() { 
     cleanup.run(); 
    } 
    public Runnable getCleanup() { 
     return cleanup; 
    } 
} 

Stage類是簡單而不變的,但它的實際行爲是由可通過lambda表達式創建的FunctionRunnable情況確定, 如果你希望。您可以使用純函數或通過提供函數和清理操作來創建和鏈接。你會得到兩個不同的函數和清理操作鏈,因此可以獨立執行它們。

+0

我同意花了我一個月的時間思考:P我接受這個答案。這是你寫的一個有趣的解決方案,但本質上的答案是:「你不能用界面和lambda表達式解決所有問題」。 –

1

沒有關於資源如何清理的更多信息,人們可以想像像

@FunctionalInterface 
public interface Stage<T,Q> { 

    Q process(T toProcess); 

    static <T,Q> Stage<T,Q> of(Stage<T,Q> stage){ 
     return stage; 
    } 

    default Stage<T,Q> withRelease(Consumer<T> releaser){ 
     return t -> { 
      Q q = process(t); 
      releaser.accept(t); 
      return q; 
     }; 
    } 
} 

,你可以調用像

Stage.of(Thing::process).withRelease(Thing::close)