メッセージの逆シリアル化を抽象化できます。最初はオブジェクトへのバッファを持っているだけの「MessageHolder」クラスがあります。それは方法を持っているでしょう:
IMessageInterface NarrowToInterface(MessageId id);
あなたのルーターがそれがどんなタイプのメッセージであるかをすでに知っているかどうかは私にはわかりませんでした。その場合、メッセージホルダーインスタンスを受け取り、そのインスタンスでNarrowToInterfaceメソッドを呼び出します。
適切なタイプのIDを渡します。ルーターがタイプを認識していない場合は、MessageHolderオブジェクトにもプロパティがあります。
MessageId GetMessageType();
ルーターは、ルーティング先を決定するためにどのメッセージタイプであるかを学習するために使用します。それがどのように実装されるかについては後で詳しく説明します。
IMessageInterfaceは、メッセージの受信者がどのタイプを予期するかを知っているため、適切なタイプにダウンキャストする抽象クラスまたはインターフェイスです。さまざまなメッセージがすべてよく知られており、ジェネリックスまたはテンプレートを使用できる場合は、NarrowToInterfaceメソッドを、戻り値をテンプレートパラメーターとして受け取るテンプレートメソッドにすることができます。これにより、型の安全性が向上します。テンプレートがない場合は、「Vistor」パターンのダブルディスパッチ手法を使用できます。詳細については、Googleの「ダブルディスパッチビジター」をご覧ください。
メッセージのタイプが明確に定義されていないか、将来的に大きくなる可能性がある場合は、ある時点で(コンパイラーで検証できない)ダウンキャストを処理する必要があります。私が提案している実装は、これを可能な限りカプセル化し、私が知る限り、結合をその絶対最小値に制限します。
また、これを機能させるには、メッセージをヘッダーの標準識別子でフレーム化する必要があります。つまり、メッセージ全体の長さとメッセージタイプのIDを持つ標準ヘッダーがあります。このようにして、ソケットエンドポイントはメッセージの基本を解析し、メッセージホルダーに入れることができます。MessageHolderは、NarrowToInterface()メソッドを実装するために、すべての異なるメッセージタイプ自体を知ることができます。または、メッセージタイプごとにNarrowToInterfaceを実装するために「IMessageDeserializer」オブジェクトを返すグローバルリポジトリが存在する可能性があります。ロードされたすべてのメッセージクライアントは、サポートするすべてのメッセージのすべてのデシリアライザーをリポジトリに登録し、必要なメッセージタイプIDをメッセージルーターに登録します。