3

ドメイン駆動設計を使用して構築しているアプリケーションのいくつかの概念に問題があります。

次のレイヤーがあります。

  • 応用
  • ドメイン
  • インフラストラクチャー

したがって、次のクラスがあるとします。

  • Order
  • EmailService
  • OrderNotificationService
  • OrderApplicationService

明らかに、Orderはドメイン層にOrderApplicationService入り、 はアプリケーション層に入ります。はEmailService、電子メールを送信するための汎用サービスであり、インフラストラクチャ レイヤーに実装されています。はOrderNotificationService、注文通知を送信するための特定の実装です。はOrderNotificationServiceを使用しEmailServiceて、実際の電子メールを送信します。

私の最初の質問はOrderNotificationService、ドメイン サービス、アプリケーション サービス、またはインフラストラクチャ サービスとして実装されるかどうかです。

次の質問では、次のオブジェクトを想定してみましょう。

  • Employee
  • SalesforceService

従業員がシステムに追加されたら、Salesforce にも追加する必要があるとしましょう。はSalesforceService、Salesforce api を使用してユーザーを登録するサービスです。SalesforceServiceアプリケーション サービスが従業員情報を送信するために使用するドメイン サービスまたは汎用インフラストラクチャ サービスとして実装されますか?

アドバイスをありがとう。

4

2 に答える 2

11

これはDDDのようには聞こえません

あなたのドメイン モデルについて語るあなたの質問にはあまりありません。「従業員がシステムとSalesforceに追加される」とおっしゃいましたが、それ以外では、ビジネス上の意味で、アプリケーションが何をするつもりなのか、私にはわかりません。「従業員」と「Salesforce」についての私の理解は、システム内のモデルの説明ではなく、言葉に慣れていることに基づいています。

あなたのモデルの観点から「オーダーアプリケーションサービス」が何を表しているのか、私にはよくわかりません。「注文」と「注文通知」が届きます。「顧客」が「注文」を行い、一部の「加入者」が「通知」を受けるように見えますが、これの多くは、設計パターンに関する私の事前知識に基づいています。

コンピュータが存在しない場合に機能するビジネス ドメイン モデルを説明できる必要があります。 アイデアを説明するためにコンピューター用語が必要な場合は、おそらくモデルの外部にある何かが混入している可能性があります。

明らかに、アプリケーション ロジックをドメイン ロジックと統合する必要がありますが、これによって問題が混乱することはありません。ただし、これを回避する方法があります。

修正方法

  1. 実装固有のクラスの代わりにインターフェースを使用して、ドメイン層でサービスをモデル化できます。これは、インターフェイス分離の原則として知られています。モデルの一部に、顧客が注文したときに担当従業員に通知することが含まれていることは理にかなっています。ただし、この通知の実装をそのモデル化された目的と結び付ける必要があるという理由は必ずしもありません。混雑したオフィスでスーパーバイザーがインターホンでアナウンスを行ったり、自動化されたシステムから電子メールが送信されたりする可能性があります。これらの例はどちらも同じビジネス目的を果たします。ドメイン層に電子メール サービスを埋め込む代わりに、IOrderNotificationService単にメソッドを含むインターフェイスを持つことができますvoid NotifyOrderReceived(Order order);. そうすれば、「電子メール」の実装やデータベースへの永続化などの不必要な問題を導入することなく、ドメイン層に必要なすべてのビジネス ロジックを利用できます。私はこれを推測していますが、あなたのOrderNotificationServiceOrderApplicationServiceは実際には同じイベントへの応答ですが、一方はデータベースに依存し、もう一方は SMTP に依存しています。どちらもインフラストラクチャの問題です。

多くの場合、単一のインターフェイスに対するコーディングで十分です。ただし、ドメイン オブジェクトが注入されたサービスまたはグローバル変数に依存するようになったという問題があります。また、これは、これらのエンティティが依存関係について知りすぎていることを示している可能性があります。顧客は、注文がどのように処理されるかの内部の仕組みを知る必要はないかもしれませんが、注文が処理され、注文したものを受け取ることだけを知る必要があります。同様に、従業員は、従業員になる前にそのことを知らないため、おそらく Salesforce に自分自身を追加しません。彼が知っているのは、彼が就職したばかりだということだけです。

この問題には非常に良い解決策があります...

  1. 「ドメイン イベント」パターンを使用できます。基本的な考え方は、ドメイン オブジェクトは何が起こったのか、どのように状態が変化したのかを知っているだけで、変更された状態の永続化や伝播については何も知る必要がないということです。それらは内部ロジックを処理し、「ドメイン イベント」を発生させます。これは、顧客が注文してから「この商品を注文しました!」と叫ぶことに似ています。または、従業員が雇われてから「よ、仕事ができた!」と叫ぶ。このアプローチを採用すると、ドメイン ロジックが大幅に簡素化され、懸念事項をより明確に分離できるようになります。Udi Dahan は一連の優れたブログ投稿を行っており、ドメイン イベント パターンを利用する背後にあるロジックを説明し、非常にシンプルでありながら非常に効果的な実装を提供しています。ここにいくつかのリンクがあります:

コードを完全に理解する前にコードをコピー アンド ペーストするのが好きなタイプの開発者の場合は、これらの投稿の 3 番目から始めることをお勧めします。それらは、Udi Dahan の思考とパターンに関する経験の進化を記録しています。最も健全なコード サンプルは、3 番目の記事に記載されています。理想的には、3 つすべてを順番に読んで、彼の論理に従い、彼のアプローチからどのように利益を得ることができるか、そしてなぜそれが「ドメイン駆動設計」を正確に表しているのかを実際に理解できるようにすることをお勧めします。

「ドメイン イベント パターン」の正当化として、2009 年に Eric Evans が画期的な本を書いてからドメイン駆動設計について学んだことをレビューしたところ、ドメイン イベントは彼の本の中で見落とされがちなコア ビルディング ブロックであることが指摘されました。彼の講演の要約はここで入手でき、プレゼンテーションへのリンクはここで入手できます

このパターンをうまく適用するのに役立つその他のリソースには、Jimmy Bogard の記事「Strengening your Domain: Domain Events 」やMartin Fowler の Domain Event articleなどがあります。Bogard には、参照リンクからの他の役立つ DDD ブログ投稿へのリンクがあります。

一般に、

ドメイン駆動設計を実際に適用してみたい場合は、何をモデル化し、何をどのような目的で実装しているのかを真に理解することで、はるかに成功するでしょう。なじみのない用語を単に使用してコードにそのようにラベル付けすることには、暗黙の価値はありません。DDD は非常に役に立ちますが、時間をかけて区別し、設計上の決定を下す理由を理解しないと、多くの不必要な抽象化と一般的な混乱を招くことになります。

于 2012-09-08T00:09:30.573 に答える
1

OrderNotificationService はドメイン層に属します。Order クラスのコラボレーターと考える場合は、Order クラスの近くに配置する必要があります。IMO、代わりに OrderNotificationService を OrderNotifier と呼ぶことができると思います。その責任は、注文状態が変更されたときに通知を公開することです。これは明らかに、具象クラスではなくインターフェイスです。これは、インフラストラクチャ層またはアプリケーション層のいずれかに属する OrderNotificatoinService によって実装される場合があります。OrderNotificationService をインターフェースにする必要はありません。

同じことが SalesforceService にも当てはまります。従業員が作成されたときに新しい従業員情報を登録する責任がある Employee クラスの共同作業者と考えてください。ドメイン層に属します。前のケースと同じように、実装ではなく役割を説明する EmployeeRegister などに名前を変更することを検討してください。代わりに SaleforceService で実装しました。

副作用の 1 つは、ドメイン オブジェクト (注文/従業員) がアプリケーション/インフラストラクチャ レイヤーのクラスに間接的に依存することです。ドメインオブジェクトが他のドメインオブジェクトによってインスタンス化されている場合、ドメインオブジェクトを作成するときにサードパーティの依存関係を注入するのは難しいかもしれません. この記事は役に立つかもしれません。http://thinkinginobjects.com/2012/09/05/abstract-factory-in-domain-modelling/

于 2012-09-07T22:44:43.810 に答える