私が取り組んでいるプロジェクトでは、ウィジェットに関するメッセージをメッセージキューを介して送信し、XMLとしてキューにシリアル化します。 XMLスキーマには、ウィジェットタイプ、コマンド名、宛先など、これらのウィジェットメッセージのすべてのタイプに共通するプロパティのタグが含まれています。また、キーと値のペアの任意のサイズのリストを含めることができ、特定のタイプのウィジェットメッセージにのみ関連するプロパティを保存できます。 WidgetMessage
クラスはこのデータをカプセル化し、WidgetMessageXmlWriter
およびWidgetMessageXmlReader
クラスはXMLとのシリアル化を提供します。
特定のメッセージをカプセル化するクラスをいくつか作成しました。たとえば、「Foo」ウィジェットのFooPlaySoundMessage
や「Bar」ウィジェットのBarSetLightPatternMessage
などです。それぞれに、ToWidgetMessage
インスタンスメソッドとFromWidgetMessage
静的メソッドがあり、WidgetMessage
クラスとの間で変換を行います。メッセージの各ファミリは、そのウィジェットタイプの抽象クラスから継承します。 FooMessage
とBarMessage
は、WidgetMessageMapping
クラスから継承します。これは、変換のためにサブクラスによって使用される共通のメッセージプロパティと保護されたメソッドを格納します。 これらのクラスはWidgetMessage
を継承しません。キーと値のコレクションプロパティと関連するメソッドを継承したくないからです。単純なキャストではなく変換の必要性。
私はAPIの単純さ(たとえばFooPlaySoundMessage msg = FooPlaySoundMessage.fromWidgetMessage(widgetMessage)
)が好きですが、機能を共有するために基本クラスで保護されたメソッドを使用しなければならず、それを公開するために静的メソッドを使用しなければならないという事実は、ここに含まれる個別のクラスまたは2つのクラス(WidgetMessageXmlWriter
およびWidgetMessageXmlReader
と同様)。一方、OOP=のポイントの一部は、データとメソッドをグループ化して、 "dumb data objects" を避けることだと思いました。
それで、データオブジェクトに変換メソッドを追加することによって正しいアイデアを持っていますか、それともその機能を別のクラスに抽出する必要がありますか?
更新:
上記の現在の設計の試みのすべての詳細において、私が解決しようとしている問題を十分に明確に説明していなかったと思います。
要約すると、強く型付けされたプロパティと、他のカスタムデータを格納するためのキーと値のペアのコレクションを持つ「ジェネリック」DTOクラスがあります。キーと値のペアが厳密に型指定されたプロパティに置き換えられていることを除いて、汎用DTOと同じデータをすべて格納するカスタムデータのセットごとにいくつかの特殊なDTOクラスが必要です。これら2つのタイプのDTO間で変換するための最良の設計は何ですか?
FooPlaySoundMessageがサウンドの再生方法と、自分自身をメッセージキュー形式にマップする方法を知っている場合、クラスには複数の責任があると言えます。実際のサウンド再生を別のクラスに直接委任する場合、あなたのFooPlaySoundMessageは基本的にデータ転送オブジェクトです。共有マッピングを共有基本クラスに配置することは、その場合私には問題ないようです。
私はおそらくそれを分離するでしょう。通常、データ転送オブジェクトにはコードがほとんどないか、まったくありません。FooPlaySoundMessageが1つとして表示されます。
ある時点で、同じデータを他の方法または他の形式(json多分?)で送信する必要があるかもしれません。今のところそれをYAGNIして分離することができます。
おそらく、共通部分を解析してメッセージタイプを検出し、特定のパーサーに委任するメッセージハンドラークラスを作成します。 FooPlaySoundXmlMessageParser。疑わしい場合は、継承よりも構成を優先します。