5

次のシナリオでの最善/優れたサービスバインディング/コミュニケーションプラクティスは何ですか (タイトルがある程度意味のあるものであることを願っています):

非同期ソケット サービス (SS) を (共通の通信エンドポイントとして) 共有するいくつかのサービス メソッドを含むビジネス レイヤー (BL)。これらのメソッドによってバインドされ、ソケット IO に使用される場合があります。

たとえば、BL は SL を取得して send(message) を呼び出し、応答を待ちます。

最初はコールバックとバインダー パターンを使用しました。バインダー パターンを使用した明確な設計 (メッセージ キューがなく、すべてがメイン スレッドで行われる) に問題があったため、現在メッセージ パターンを試しています。

基本的に、BL サービスと SL サービスには Messenger と対応するハンドラーがあります。

private final IncomingHandler incomingHandler = new IncomingHandler();
private final Messenger messengerReceiver = new Messenger(incomingHandler);
private class IncomingHandler extends Handler {
  @Override
  public void handleMessage(Message msg) {
  ...
  }
}

BL の 1 つは、実装する AbstractAccountAuthenticator サブクラスです。

addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options){
     ...
     if(socketConnectionState != null){
        Bundle authBundle = new Bundle();
        authBundle.putString("password", password);
        authBundle.putString("username", account.name);
        Message message = Message.obtain(null, SocketConnectionHandler.SEND_REQUEST, authBundle);
        message.replyTo = messengerReceiver;
        socketConnectionState.getMessenger().send(message);
...}

また、SL を使用して authToken を取得します。addAccount() メソッドは、バンドルですぐに結果 (authToken) を返すか、代わりに応答コールバック メソッドを呼び出す必要があります。SL 経由で addAccount 内の認証トークンをリクエストした場合、結果を返すにはどうすればよいでしょうか?

ここでの主な問題は、結果が呼び出し元のメソッド (addAccount()) ではなく、messengerReceiver ハンドラーに返されることです。

私が考えることができる唯一の方法は、メッセージ ハンドラーによって応答が提供され、その後 addAccount() メソッド内で取得される BlockingQueue ですが、これは非常に不快に感じます。他のアイデア?正しいアプローチですか?

4

1 に答える 1

0

あなたの問題は、応答がメッセージハンドラーの関心事であるという前提を述べた場合にのみ発生します。

私は最近、職場で同じ問題を抱えていました。メッセージハンドラの引数リストを拡張することで解決しました

public interface MessageHandler {
    public void receivedMessage(Message message, ResponseChannel channel);
}

interface ResponseChannel {
    public void respond(Message response);
}

interface Message {}

もちろん、 の各インスタンスにメンバー変数を導入することもできますがMessageHandler、それによってステートレス性が取り除かれます。最終的に、両方のアプローチの背後にある原則は同じです。

それでも、別の可能性があります。

関心の分離

前に述べたように、応答に応答するという追加の責任をメッセージ ハンドラーに割り当てると、味が悪くなります。メッセージ ハンドラーには、着信メッセージを受信する役割が既にあります。

彼は着信メッセージを処理します。これは、関連するパラメーターを抽出し、メッセージを関係者に転送するか、モデルまたはコントローラーで適切なメソッドを呼び出すという短いプロセスである必要があります。

メッセージ ハンドラーは論理的に送受信コンポーネントの一部ではなく、そこに登録され、他のすべてのメッセージ ハンドラーおよびその呼び出しとスレッドまたはスレッド プールを共有するため、これは短くて網羅的なプロセスである必要があります。

では、応答をどのように処理する必要がありますか? したがって、ハンドラーの責任でない場合は、ハンドラーから通知を受けた当事者が対応する必要があります。

public interface MessageHandler {
    public void receivedMessage(Message message, ApplicationContext context);
}

interface ApplicationContext {
    public void notifyUserJoined(String name);
}

interface Message {
    public String getUser();
}
于 2015-04-03T21:50:40.007 に答える