2016-07-11 9 views
1

問題は、Firebaseからデータを初期化して取得することから得られますが、私はこれを擬似に変換して、使い慣れていない人も貢献できるようにします。問題がにClassAとClassBのの呼び出しがタイムラインではかなり接近していると私はmyRemoteDBClassInstanceの初期化の前または後にasyncFetchを呼び出すために取得する場合、私は知らないということです `ここで正しいアーキテクチャ設計は何ですか?

//Given the following API (from Firebase) 
MyRemoteDBClass.asyncAuthenticate(initCompletedListener); 
MyRemoteDBClass.asyncDataFetch(fetchCompletedListener) 
// of course you have to authenticate before fetching the data 
Class MyClassA.init() 
{ 
    MyRemoteDBClass myRemoteDBClassInstance = new MyRemoteDBClass(); 
    myRemoteDBClassInstance.asyncAuthenticate(some_listener); 
} 
// Then somewhere in the app: 
Class MyClassB.asyncDataFetch(MyRemoteDBClass myRemoteDBClassInstance){ 
    myRemoteDBClassInstance.asyncDataFetch(myClassBObject_as_listener) 
}` 

:以下のコードを考えてみてください。既に完了しました。
initが完了した後、MyClassBのmyRemoteDBClassInstance.asyncDataFetchメソッドを呼び出すことをどのようにしてお約束できますか?

+0

'init()'操作をブロックするようにして、認証が完了するのを待ちます。リスナと 'init()'メソッドの間で共有される 'CountDownLatch'(値1で初期化)が必要です。リスナーで 'latch.countDown()'と 'init()' - 'latch.await()' –

答えて

2

some_listenerCompletableFutureにして、asyncAuthenticateが完成したら解決してください。私はそれが後できれいに呼び出して、私たちが後でVoidよりも有用な何かを返すために、または非同期の連鎖を実行することを可能にするために、将来を使用したい

CompletableFuture<Void> future = new CompletableFuture<>(); 
Listener some_listener = new Listener() { 
    @override onAuthComplete() { future.complete(null); } 
    //... 
}; 

// Guts of your MyClassA.init 
MyRemoteDBClass myRemoteDBClassInstance = new MyRemoteDBClass(); 
myRemoteDBClassInstance.asyncAuthenticate(some_listener); 

// ... 

// Guts of your MyClassB.asyncDataFetch 
future.get(); // Wait for auth to complete 
myRemoteDBClassInstance.asyncDataFetch(other_listener); 

:それはこのような何かを探して終わるでしょう。

+0

を実行することができます。この場合、私が提案したアプローチを使用する必要があります。 –

+1

@ GauravaAgarwalこれは、望ましい動作に依存します。マイケルのアプローチは、必要な状態に達するのを「待つ」。フェッチを遅らせるが、最後に行う。あなたのアプローチは、フェッチを行わないことに終わります。 – Fildor

+0

CompletableFutureのアプローチは面白いです。私はそれを徹底的に調べます。ありがとう – user3734429

1

MyClassAの状態を初期化して、初期化されているかどうかを記録します。 MyClassBでこの状態を確認します。

Class MyClassA.init() 
{ 
    MyRemoteDBClass myRemoteDBClassInstance = new MyRemoteDBClass(); 
    myRemoteDBClassInstance.asyncAuthenticate(some_listener); 
    static boolean initialized = true;//only sample code 
} 
static boolean MyClassA.isInitialized() {return initialized ;} 

// Then somewhere in the app: 
Class MyClassB.asyncDataFetch(MyRemoteDBClass myRemoteDBClassInstance){ 
    if (MyClassA.isInitialized()) { //only sample code 
    myRemoteDBClassInstance.asyncDataFetch(myClassBObject_as_listener) 
} 
} 
+0

ブール値が別のスレッドの中から設定されているので、慎重にしたい。私は少なくともAtomicBooleanを代わりに使用したいと思います。 'static'変数を使うと、あなたのコードの単体テストを楽しくすることができます。そして、' MyClassA'と 'MyClassB'の間に不必要なバインディングが導入されます。 –

+0

初期化されていない場合はどうなりますか?それまで繰り返す? – user3734429

+0

@MichaelAndersonクラスが初期化されているかどうかをチェックする基本的な解決策を提供します。ユーザが非常に基本的な制限付きコードを投稿しただけなので、 'initialized'がインスタンス変数になることができるかどうかは明確な可視性がありません。 –

関連する問題