2016-11-19 3 views
2

不変オブジェクトとしてアプリケーションの残りの部分に渡したいオブジェクトを構築したいと思います。しかし、ここでの問題は、オブジェクトの構築時にはいくつかのフィールドを直接利用できますが、RPCコールからの応答が必要なものもあります。 RPC呼び出しには時間がかかりますが、呼び出し元がオブジェクトの作成時に渡されるフィールドを使用したいので、この時間に呼び出し元をブロックしたくありません。私は念頭に置いてデザインをしていますが、標準パターンがあるかどうかを知りたがっています。最終的な不変性を持つ不変オブジェクトのデザインパターン

次の例は、私が探しているものを示しています。

public class Player { 
    private int name; // Available at construction time 
    private int age; // Available at construction time 

    private String profileUrl; // Need to get this from an RPC call 

    // useful for checking whether we have profileUrl 
    private boolean profileUrlAvailable = false; 

    Player(int name, int age) { 
    this.name = name; 
    this.age = age; 
    } 

    // usual getter methods 

    // Package protected for immutability 
    void setProfileUrl(String profileUrl) { 
    this.profileUrl = profileUrl; 
    this.profileUrlAvailable = true; 
    } 

    public boolean hasProfileUrl() { 
    return profileUrlAvailable; 
    } 

    // throws if profile url is not yet available. 
    public String getProfileUrl() { 
    if (!profileUrlAvailable) { 
     throw new IllegalStateException("Profile url not available"); 
    } 
    return profileUrl; 
    } 
} 

この例はスレッドセーフではありません。この例は注意が必要です。興味のある発信者にプロファイルURLがいつ利用可能かを知らせるために、profileUrlが利用可能になったときに通知されるコール可能なものを登録するメソッドを公開します。

最終的に利用できるprofileUrlに似たいくつかのフィールドを追加すると、このアプローチはうまくいきません。私はこれを解決する方法を提案したかった。

profileUrlに似たフィールドがすべて同時に使用できるようにする(つまり、1つのメソッドを使用して設定する)ことは簡単ですか?

+0

インターフェイスを使用して、外部コードで使用するメソッドを公開し、単に変更するメソッドを公開しないのはなぜですか? – AgilePro

+0

確かに、それは外界には変更できないことを確認するでしょう。最終的に使用可能なフィールドを扱う際の問題の他の部分について考えてみましょう:hasField()、getField()&フィールドがいつ利用可能かを通知します。私は、内部クラスのすべてのフィールドを組み合わせて、単一呼び出しで設定し、これが設定されたときに世界に通知することができます。しかし、それを行うより良い方法はありますか? – Bajji

+0

Builder Patternのようなものはあなたのために働くでしょうか? –

答えて

0

Lazy initializationはあなたのニーズに合っていますか?

コードスニペット:

public class Player { 
private int name; // Available at construction time 
private int age; // Available at construction time 

private String profileUrl = null; // Need to get this from an RPC call 

Player(int name, int age) { 
    this.name = name; 
    this.age = age; 
} 

// usual getter methods 

public String getProfileUrl() { 
    if (profileUrl == null) { 
    profileUrl = Remote.getProfileUrl(); 
    } 
    return profileUrl; 
} 
} 

あなたはこの場合getProfileUrlには、アクセサメソッドにRPCを移動します。 最初の呼び出しだけが、リモートプロシージャが完了するのを待って実際にブロックします。

このような重い初期化を必要とするフィールドのその他のアクセサメソッドは、同じように見えます。

Playerクラスをこのように使用して、将来の呼び出しでprofileUrlをキャッシュすることができれば、あなたの問題を解決し、このパターンの目標を達成できます。

+0

これは良い答えです。しかし、彼がそうした方法でRPCにアクセスできるなら、OPはそれを実行できたと思いませんか? – Jay

関連する問題