2017-11-20 18 views
0

APIメソッドがListenableFuture<T>を返し、戻り値がSettableFuture<T>として実装されているとします。 SettableFutureにキャストできず、不正なクライアントによって完了できない 'ListenableFuture`を返す方法はありますか?読み取り専用SettableFuture参照

したがって、ListenableFutureの読み取り専用のビューです。 .unmodifiableCollectionでコレクションをラップするのと同様です。

答えて

2

最も簡単な方法は、おそらくです:その未来はまだ人々がそれをcancelできるという意味で、「書き込み可能」であることを

return Futures.transform(future, x -> x);

注意。ユーザーが元の未来をキャンセルしないようにしたい場合 - 私はあなたがこれを気にするとは思わないが、とにかく "読み込み専用"と言っていたので、

return Futures.nonCancellationPropagating(future);

+1

そういえば、そう、私もキャンセルを気に!今すぐ失敗したテストを書く。これを指摘してくれてありがとう。 – tariksbl

0

これを実現するためのデザインパターンは、デコレータパターンです。 Guavaの作者が、このタイプの要求に対して転送先となるものを設計した方法を見てみる価値があります。ここで

は、例えば抽象クラスForwardingListenableFutureから抽出されたいくつかのコードです:

/** 
* A {@link ListenableFuture} which forwards all its method calls to another 
* future. Subclasses should override one or more methods to modify the behavior 
* of the backing future as desired per the <a 
* href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>. 
* 
* <p>Most subclasses can just use {@link SimpleForwardingListenableFuture}. 
* 
* @param <V> The result type returned by this Future's {@code get} method 
* 
* @author Shardul Deo 
* @since 4.0 
*/ 
public abstract class ForwardingListenableFuture<V> extends ForwardingFuture<V> implements ListenableFuture<V> { 

    /** Constructor for use by subclasses. */ 
    protected ForwardingListenableFuture() {} 

    @Override 
    protected abstract ListenableFuture<V> delegate(); 

    @Override 
    public void addListener(Runnable listener, Executor exec) { 
    delegate().addListener(listener, exec); 
    } 
    ... 

することができますように、このクラスの責任はListenableFutureをラップし、クライアントへの実際の実装を隠すことである - 最後の両方のユーザーdelegate()メソッドが具体的な型の代わりにListenableFutureを返すのを見ると、実装者は、

実際が包まれ、将来にsetを呼び出すためのクライアントを防ぐことができますあなたがラップにニーズを非表示にするかForwardingListenableFutureの実装とそれを「飾る」実装ListenableFutureオブジェクトを、作成するコード。 javadocが示唆しているように、SimpleForwardingListenableFutureのサブクラス化は、委任されたメソッドに潜在的な副作用を導入することなく、その仕事を行います。

関連する問題