DTOとドメインモデルの適切な設計に関して、私が持っているいくつかの質問に誰かが答えられることを願っていました。現在、SOAP APIの活用を含むプロジェクトに取り組んでいます。
SOAPで作業しているので、提供されたWSDLファイルを使用して多数のオブジェクト(DTO)を生成するという追加の利点があります。その後、いくつかのコマンドを作成して、各リクエストの意図をより適切にカプセル化し、APIへのインターフェースを簡素化します。
各コマンドハンドラーには、要求を正常に完了するために必要なすべてのデータを格納する、関連付けられた「コマンド」オブジェクトがあります。
私は実際にこのアプローチに関して3つの質問があります。
1)コマンドハンドラーを直接呼び出して、呼び出し元としてコマンドバスを置き換えるのは珍しいことではありませんか。明らかに、コマンドを(少なくともこれらの選択したインスタンスでは)キューイングアプリケーションに渡すことができなくなり、コマンドを非順次で実行できるようになります。
ただし、実行時にAPI応答データを実際に解析する必要があるいくつかのケースを特定しました。これは、アプリケーションの設計における潜在的な問題と解釈できますか?
2)現在、リクエストデータを不変のコマンドオブジェクトに渡す前に検証を行っています。ただし、コマンドを初期化する前に、DB/CLIからのデータを解析する必要がある場合があります。
その結果、検証ロジックをコマンドオブジェクト自体に配置することを検討しました。検証が失敗すると、例外がスローされる可能性があります。これは合理的なアプローチのように見えますか、それとも私は再びいくつかの設計原則に違反していますか?
3)これは馬鹿げているように聞こえるかもしれませんが、ドメインオブジェクトとDTOの違いは何ですか。コマンドオブジェクト自体がDTOと呼ばれるのを聞いたことがありますが、それらはドメインレイヤーに属しているように見えます(私が間違っていない限り)。
コマンドオブジェクトをDTOまたはドメインモデルとしてより正確に説明できますか?
再度、感謝します。フィードバックに感謝します。
残念ながら、最初の質問の意味がわからないため、お答えすることはできませんが、残りの問題についてはお手伝いできます。
2)現在、リクエストデータを不変のコマンドオブジェクトに渡す前に検証を行っています。ただし、コマンドを初期化する前に、DB/CLIからのデータを解析する必要がある場合があります。
その結果、検証ロジックをコマンドオブジェクト自体に配置することを検討しました。検証が失敗すると、例外がスローされる可能性があります。これは合理的なアプローチのように見えますか、それとも私は再びいくつかの設計原則に違反していますか?
無効なオブジェクトを最初に処理して、作成後に検証が必要になるのはなぜですか。
これが発生する理由は2つあります。
これらのケースはどちらも悪いですが、2番目のケースははるかに悪いです。
最初のケースは、ユーザーが制御できる変数を使用するときに発生する可能性があります。つまり。彼は好きなものを入力できます。これは実際には制御できないものであるため、オブジェクトを作成する前に必ずallオプションをチェックする必要があります。
2番目のケースは、クラスをモデル化しても、クラスが想定されていることを実行していないと信頼している場合に発生します。おそらく、内部構造の多くを公開しすぎて、プログラマーがオブジェクトを操作する方法にあまりにも多くの可能性を与え、おそらく実際のメソッドの代わりに単純なゲッターとセッターを持っていますか?
2番目のケースはもっと悪いと言った。さらに悪いのは、自分のドメインを信頼していないためです。そして、あなたがそれを信頼できない場合、誰ですか?
3)これは馬鹿げているように聞こえるかもしれませんが、ドメインオブジェクトとDTOの違いは何ですか。コマンドオブジェクト自体がDTOと呼ばれるのを聞いたことがありますが、それらはドメインレイヤーに属しているように見えます(私が間違っていない限り)。
[〜#〜] dto [〜#〜]は非常にシンプルで愚かなオブジェクトであり、ゲッターとセッターのみで構成され、一見関連のある小さなチャンクを接着します情報をまとめて1つの大きな構造にすることで、データ要求を減らすことができます。
Martin Fowler は、DTOオブジェクトの簡単な例を提供します。
ドメインモデルは、ビジネスロジックを含むオブジェクトです。これは、set
で始まるメソッドを持たないオブジェクトであり、Tell、Do n't askの原則に従う必要があります。ドメインはアプリケーションのコアです。ドメインオブジェクトがすべて正常に動作することを確認し、無効な操作でドメイン例外をスローして、常に有効な状態であることを確認します。
Tell、Do n't ask原則はカプセル化を提供します。これは次のようになります。
if (personObject.GetSex() == "Male") { ... }
これに:
if (personObject.IsMale()) { ... }
Person
、Sex
、string
の場合、enum
クラスを使用するプログラマは、boolean
プロパティがどのように表されるかを気にしなくなりました。それが気にする唯一のものはPerson::IsMale : boolean
方法。
ドメインモデルの要約:これは、直接結び付けられているデータを含むオブジェクトです(永続化ロジックは許可されていません。オブジェクトは、自身のデータのみを処理する必要がありますデータ)および操作をカプセル化して、一度作成されると、無効な状態になることはありません。
私はこれらの用語について正確にはあまり経験していませんが、あらゆる種類の奇妙な依存関係を持つ非常に複雑なデータ型を使用して多くのシリアル化を行ったので、POCO(TLDR;それらをPOCOに保つ)を管理するための2セントです。
実行時にAPI応答データを実際に解析する必要があるいくつかのケースを特定しました。これは、アプリケーションの設計における潜在的な問題と解釈できますか?
はい、取得したすべてのデータをできるだけ早く処理する必要があります。そうしないと、アプリケーションのすべての層で大量のスパゲッティコードが発生し、「オンデマンド」でデシリアライズが行われる可能性があります。
検証ロジックをコマンドオブジェクト自体に配置することを検討しました。検証が失敗すると、例外がスローされる可能性があります。これは合理的なアプローチのように見えますか、それとも私は再びいくつかの設計原則に違反していますか?
はい、一部の検証には他のオブジェクトからのデータが必要な場合があり、一部には時間を要する場合があります。検証に使用される高価なアルゴリズムの結果には、複数回アクセスする必要がある場合があります。検証が失敗した場合は、検証が失敗したことをWebサーバーに通知するなど、何かを行う必要がある場合があります。そのためには、いくつかのデリゲートまたはイベントを使用するか、そこで実行する必要があります。どちらも、ネットワークライブラリを呼び出すことを意味します。きれいではなく、DTOで他のDTOを作成することを意味します。