14

いくつかの非同期通信状況 (イベント駆動型 XML 解析、NSURLConnection 応答処理など) を扱っています。私の問題を簡単に説明しようとします:

私の現在のシナリオでは、サービス プロバイダー (xml パーサーと通信したり、ネットワーク通信を行ったりすることができます) と、サービス プロバイダーにタスクの一部を非同期で実行するように依頼できるクライアントがあります。このシナリオでは、サービス プロバイダーが処理を終了したときに、結果をクライアントに返す必要があります。

この種のものを実装するための一種のパターンまたは経験則を見つけようとしていますが、3つの可能な解決策があります。

1. 委任パターンを使用します。クライアントはサービス プロバイダーの委任であり、タスクの完了時に結果を受け取ります。

2. ターゲット/アクション アプローチを使用します。クライアントはサービス プロバイダーにタスクを実行するように要求し、タスクの完了後にサービス プロバイダーによって呼び出される必要があるセレクターを渡します。

3. 通知を使用します。

(更新) ソリューション #2 (ターゲットとアクション) をしばらく試した後、私の場合は委任アプローチ (#1) を使用する方がよいという結論に達しました。私が見ているように、ここに各オプションの長所と短所があります:

委任アプローチ:

  • 1 (+)オプション 1 の利点は、クライアントがサービス プロバイダーのデリゲート プロトコルを実装する必要があるため、コンパイル時のエラーをチェックできることです。

  • 1 (-)これは、デリゲート プロトコルを実装する必要があるため、クライアントがサービス プロバイダーと密結合になるため、欠点でもあります。

  • 1 (+)これにより、プログラマーはコードを簡単に参照して、サービス プロバイダーが呼び出して結果を渡すクライアントのメソッドを見つけることができます。

  • 1 (-)クライアントの観点からは、サービス プロバイダーが結果を取得した後、どのメソッドが呼び出されるかを見つけるのはそれほど簡単ではありません。デリゲート プロトコル メソッドに移動するだけで簡単ですが、#2 のアプローチはより直接的です。

  • 1 (-)もっとコードを書く必要があります: デリゲート プロトコルを定義して実装します。

  • 1 (-)また、委任パターンを使用して、実際に動作を委任する必要があります。このシナリオは、意味的に言えば、委任の正確なケースではありません。

アクション/ターゲットアプローチ

  • 2 (+)オプション 2 の利点は、サービス プロバイダー メソッドが呼び出されるときに、コールバック アクションを指定する @selector も指定する必要があるため、プログラマーは結果を処理するために呼び出されるメソッドをその場ですぐに知ることができることです。

  • 2 (-)これに対して、サービス プロバイダーのコードを参照しているときに、クライアントでどのメソッドがコールバックされるかを見つけるのは困難です。プログラマーは、サービス呼び出しに移動して、どの @selector が渡されているかを確認する必要があります。

  • 2 (+)より動的なソリューションであり、パーツ間の結合が少なくなります。

  • 2 (-)おそらく最も重要なことの 1 つは、クライアントが存在しないセレクターをサービス プロバイダーに渡すことができるため、実行時エラーや副作用が発生する可能性があることです。

  • 2 (-)シンプルで標準的なアプローチ (#performSelector:withArgument:withArgument:) を使用すると、サービス プロバイダーは最大 2 つの引数しか渡すことができません。

通知:

  • 通知は、複数のオブジェクトを更新する必要がある場合に使用することになっているため、選択しません。また、この状況では、デリゲート/ターゲット オブジェクトに、結果が構築された後に何をすべきかを直接伝えたいと思います。

結論: この時点では、委任メカニズムを選択します。このアプローチにより、安全性が向上し、コードを簡単に参照して、デリゲートにサービス プロバイダー アクションの結果を送信した結果を追跡できます。このソリューションのマイナス面は次のとおりです。より静的なソリ​​ューションであり、より多くのコード (プロトコル関連のもの) を記述する必要があり、意味的に言えば、サービス プロバイダーは何も委任しないため、委任については実際には話していません。 .

何か不足していますか?何をお勧めしますか?その理由は何ですか?

ありがとう!

4

3 に答える 3

3

3 番目のオプションである通知を見逃していました。

新しいデータが利用可能であることを示すサービス プロバイダーからの通知をクライアントに監視させることができます。クライアントがこの通知を受け取ると、サービス プロバイダーからのデータを消費できます。

これにより、適切な疎結合が可能になります。ただし、決定の一部は、プッシュ/プル システムが必要かどうかにかかっています。

于 2009-12-22T19:54:24.687 に答える
0

とても良い質問です。

私はまだ(私は初心者なので)、どのデザインパターンが他のパターンよりも優れているかについてコメントする資格があるとは思いません。ただし、ポイント2で述べた欠点(実行時の例外)は、次の方法で回避できることをお伝えしたいと思います。

if([delegate respondsToSelector:callback]){
    //call to callback here
}

オプションを比較検討するのに役立つことを願っています

于 2009-12-22T19:00:12.570 に答える
0

委任アプローチのもう 1 つの欠点は、サービス プロバイダーが持てる委任を1 つだけにすることです。サービス プロバイダーがシングルトンで、複数のクライアントがある場合、このパターンは機能しません。

これにより、私はアクション/ターゲット アプローチを採用するようになりました。私のサービス プロバイダーは状態を保持し、複数のクライアント間で共有されます。

于 2010-07-06T13:28:29.797 に答える