タグ付けされた質問 「domain-driven-design」

ドメイン駆動設計(DDD)は、実装を進化するモデルに接続することにより、複雑なニーズに対応するソフトウェアを開発するためのアプローチです。

4
ドメインモデルの検証を配置する場所
ドメインモデル検証のベストプラクティスをまだ探しています。ドメインモデルのコンストラクターに検証を入れるのは良いですか?私のドメインモデル検証の例は次のとおりです。 public class Order { private readonly List<OrderLine> _lineItems; public virtual Customer Customer { get; private set; } public virtual DateTime OrderDate { get; private set; } public virtual decimal OrderTotal { get; private set; } public Order (Customer customer) { if (customer == null) throw new ArgumentException("Customer name must …

7
RESTful APIは貧弱なドメインモデルを奨励する傾向がありますか?
ドメイン駆動設計とRESTの両方をサービス指向アーキテクチャに適用しようとしているプロジェクトに取り組んでいます。100%REST準拠について心配する必要はありません。リソース指向のHTTP API(〜RichardsonのREST成熟度モデルのレベル2)を構築しようとしていると言った方が良いでしょう。それでも、RPCスタイルのHTTPリクエストの使用は避けようとしています。つまり、例えば、POSTdo を使用するのではなく、RFC2616に従ってHTTP動詞を実装しようとしますIsPostalAddressValid(...)。 ただし、これに重点を置くことは、ドメイン駆動設計を適用しようとする試みを犠牲にしているようです。だけではGET、POST、PUT、DELETEおよびその他のいくつかのほとんど使用されない方法で、私たちは汚いサービスを構築する傾向があり、そして汚いサービスは、貧血のドメインモデルを持っている傾向があります。 POST:データを受信し、検証し、データにダンプします。GET:データを取得して返します。実際のビジネスロジックはありません。また、サービス間でメッセージ(イベント)を使用しますが、ビジネスロジックのほとんどは最終的にその周りに構築されるように思われます。 RESTとDDDは何らかのレベルで緊張していますか?(または、ここで何かを誤解していますか?他の何か間違っているのでしょうか?)RPCスタイルのHTTP呼び出しを回避しながら、サービス指向アーキテクチャで強力なドメインモデルを構築することは可能ですか?

1
なぜキューとしてのデータベースがそんなに悪いのか?[閉まっている]
私はこの記事を読んだばかりで、混乱しています。 1つのwebappと1つの別個のアプリケーションが「ワーカー」として動作し、両方が同じデータベースを共有しているとしましょう。 ああ、私は「共有」と言いました。しかし、この記事は何について警告していますか?: 第4に、アプリケーション(またはサービス)間でデータベースを共有することは悪いことです。そこに無定形の共有状態を置くのはあまりにも魅力的であり、それを知る前に、巨大に結合したモンスターができます。 =>反対。別個のアプリケーションが依然として同じユニットの一部である場合があります。したがって、この場合、「カップリングの問題」という概念は意味がありません。 続けましょう:webappはクライアントHTTPリクエストを処理し、いつでもいくつかの集約(DDD用語)を更新して、対応するドメインイベントを生成します。 ワーカーの目標は、必要なジョブを処理することにより、これらのドメインイベントを処理することです。 ポイントは: イベントデータをワーカーに渡す方法 読んだ記事が推進する最初の解決策は、優れたメッセージ指向ミドルウェアであるRabbitMQを使用することです。 ワークフローは簡単です: Web dynoがイベントを生成するときはいつでも、RabbitMQを介してイベントを発行し、ワーカーにフィードします。 欠点は、潜在的な送信エラーやハードウェアの問題に対処せずに、集約更新のコミットとイベントの発行の間の即時の一貫性を保証するものがないことです。それは別の主な問題です。 例:集約の更新が成功せずにイベントが発行された可能性があり、その結果、ドメインモデルの誤った表現を表すイベントが発生しました。 グローバルXA(2フェーズコミット)が存在すると主張できますが、すべてのデータベースまたはミドルウェアに適合するソリューションではありません。 それでは、この即時の一貫性を確保するための優れたソリューションは何でしょうか?: IMO、集計更新と同じローカルトランザクションでデータベースにイベントを保存します。 シンプルな非同期スケジューラが作成され、データベースから現在の未公開イベントをクエリし、それらをRabbitMQに送信します。RabbitMQはワーカーにデータを入力します。 しかし、なぜwebapp側で余分なスケジューラーが必要なのか、そしてところで:この場合RabbitMQが必要なのはなぜですか? このソリューションでは、特にデータベースが共有されているため、RabbitMQは不要である可能性があります。 実際、どのような場合でも、即時一貫性にはデータベースからのポーリングが含まれることがわかりました。 したがって、なぜワーカーはこのポーリングに直接責任を負わないのでしょうか? したがって、なぜWeb上の多くの記事が、データベース指向のキューイングを批判しているのに、メッセージ指向のミドルウェアを宣伝しているのか疑問に思います。 記事の抜粋: シンプルで、仕事に適したツールを使用します。このシナリオは、メッセージングシステムを求めています。上記のすべての問題を解決します。これ以上のポーリング、効率的なメッセージ配信、完了したメッセージをキューからクリアする必要、共有状態はありません。 そして、即時の一貫性は無視されますか? 要約すると、データベースが共有されているかどうかにかかわらず、ケースが何であれ、データベースポーリングが必要なようです。 いくつかの重要な概念を見逃しましたか? ありがとう

10
GUIDを主キーとして使用する
通常、データベースの主キーとして自動インクリメントIDを使用します。GUIDを使用する利点を学ぼうとしています。私はこの記事を読みました:https : //betterexplained.com/articles/the-quick-guide-to-guids/ これらのGUIDは、アプリケーションレベルでオブジェクトを識別するために使用されることを理解しています。データベースレベルでプライマリキーとしても保存されますか。たとえば、次のクラスがあったとします: public class Person { public GUID ID; public string Name; .. //Person Methods follow } メモリ内に新しい人物を作成し、その人物をデータベースに挿入したいとします。これをやってもいいですか: Person p1 = new Person(); p1.ID=GUID.NewGUID(); PersonRepository.Insert(p1); GUIDを主キーとする数百万の行を含むデータベースがあったとします。これは常に一意ですか?GUIDを正しく理解していますか? 以前にこの記事を読んだ:http : //enterprisecraftsmanship.com/2014/11/15/cqs-with-database-generated-ids/。GUIDと整数の間の幸せな媒体を主キーとして推奨するように見えるので、少し混乱します。 編集11/06/18 Guidsはintよりも自分の要件に適していると信じるようになりました。私は最近CQRSをより多く使用しており、GUIDはよりうまく適合しています。 一部の開発者は、GUIDをドメインモデルの文字列としてモデル化することに注意してください。例:https : //github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/ Buyer.cs-この場合:IdentityGuidは文字列としてモデル化されたGUIDです。ここに記載されていること以外にこれを行う理由はありますか?カスタム値オブジェクトまたはGUIDを分散システムのエンティティ識別子として使用しますか?。GUIDを文字列としてモデル化するのは「通常」ですか、それともモデルとデータベースでGUIDとしてモデル化する必要がありますか?

3
アプリケーションまたはドメインサービスのDDDリポジトリ
私は最近DDDを勉強していますが、DDDでリポジトリを管理する方法について質問があります。 実際、私は2つの可能性に出会いました: 最初の1つ 私が読んだサービスを管理する最初の方法は、アプリケーションサービスにリポジトリとドメインモデルを挿入することです。 このように、アプリケーションサービスメソッドの1つで、ドメインサービスメソッドを呼び出し(ビジネスルールをチェック)、条件が良好な場合、データベースからエンティティを永続化/取得するために、リポジトリが特別なメソッドで呼び出されます。 これを行う簡単な方法は次のとおりです。 class ApplicationService{ constructor(domainService, repository){ this.domainService = domainService this.repository = repository } postAction(data){ if(this.domainService.validateRules(data)){ this.repository.persist(new Entity(data.name, data.surname)) } // ... } } 二つ目 2番目の可能性は、代わりにdomainService内にリポジトリを挿入し、ドメインサービスを介してのみリポジトリを使用することです。 class ApplicationService{ constructor(domainService){ this.domainService = domainService } postAction(data){ if(this.domainService.persist(data)){ console.log('all is good') } // ... } } class DomainService{ constructor(repository){ this.repository …

5
エンティティオブジェクトをデータ転送オブジェクトとして使用することをお勧めしますか?
エンティティフレームワークが、レイヤー間でデータを転送するために同じプロパティを持つ新しいオブジェクトを作成するロジックを提供しないのはなぜですか? エンティティフレームワークで生成したエンティティオブジェクトを使用します。

2
ビジネスロジックが変更されたときに失敗した場合、単体テストは脆弱と見なされますか?
以下のコードをご覧ください。女性の性別を持つ人がoffer1に適格であるかどうかをテストします。 [Fact] public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale() { var personId = Guid.NewGuid(); var gender = "F"; var person = new Person(personId, gender); var id = Guid.NewGuid(); var offer1 = new Offer1(id,"Offer1"); Assert.False(offer1.IsEligible(person)); } この単体テストは成功します。ただし、今後「Offer1」が女性に提供されると、失敗します。 言うことは受け入れられますか?オファー1を取り巻くビジネスロジックが変更された場合、ユニットテストは変更されなければなりません。データベースによっては、ビジネスロジックが次のように変更される場合があります(一部のオファーでは)。 update Offers set Gender='M' where offer=1; そして、このようなドメインモデルの場合には: if (Gender=Gender.Male) { //do something } また、背後のドメインロジックが定期的に変更を提供する場合と、そうでない場合もあることに注意してください。

1
ドメインイベントを使用するか、アプリケーションレイヤーにすべてを調整させるかの選択方法
ドメイン駆動設計への最初のステップを設定し、ブルーブックとすべてを購入しました。特定のソリューションを実装するための3つの方法を見ています。記録のために:私はCQRSまたはイベントソーシングを使用していません。 ユーザーリクエストがアプリケーションサービスレイヤーに入ってきたとします。その要求のビジネスロジックは(何らかの理由で)エンティティ上のメソッドとドメインサービス上のメソッドに分けられます。これらのメソッドを呼び出すにはどうすればよいですか? これまでに収集したオプションは次のとおりです。 アプリケーションサービスが両方のメソッドを呼び出すようにします メソッドインジェクション/ダブルディスパッチを使用して、ドメインサービスをエンティティにインジェクトし、エンティティに実行させてからドメインサービスのメソッドを呼び出します(または逆に、ドメインサービスがエンティティのメソッドを呼び出すようにします) エンティティメソッドでドメインイベントを発生させ、そのハンドラーがドメインサービスを呼び出します。(私が話しているドメインイベントの種類は、http://www.udidahan.com/2009/06/14/domain-events-salvation/です) これらはすべて実行可能だと思いますが、どちらかを選択することはできません。私はこれについて長い間考えていましたが、3つのセマンティックの違いがもはや見られなくなるまでになりました。何を使うべきかのガイドラインを知っていますか?

2
DDD-アグリゲートルートのリポジトリはアグリゲートの保存を処理しますか?
既存のアプリケーションのグリーンフィールドモジュールにDDDのようなアプローチを使用しています。アーキテクチャが原因で100%DDDではありませんが、いくつかのDDDの概念を使用しようとしています。:2つのエンティティからなる-私は(私はまだDDDについて学んだ私はそれが適切な用語だと思う)有界コンテキストを持っているConversationとMessage。メッセージは会話なしでは存在せず、システム内のすべてのメッセージは会話の一部であるため、会話がルートです。 私が持っているConversationRepository、データベース内の会話を見つける(それは本当に多くのゲートウェイのように、私は用語「リポジトリ」を使用しますが)クラスを。会話を見つけると、(ファクトリを介して)その会話のメッセージのリストも作成します(プロパティとして公開されます)。これはMessageRepository、会話が取得されたときにのみ存在するため、本格的なクラスは必要ないと思われるため、物事を処理する正しい方法のようです。 ただし、メッセージの保存に関しては、メッセージの集約ルートであるため、これはConversationRepositoryの責任ですか?つまり、ConversationRepositoryで、たとえばAddMessageMessageをパラメーターとして受け取り、データベースに保存するというメソッドが必要ですか?または、メッセージを検索/保存するための別のリポジトリを用意する必要がありますか?論理的なことは、エンティティごとに1つのリポジトリのようですが、「コンテキストごとに1つのリポジトリ」も聞いたことがあります。

4
DDDでは、検証アプリケーションロジックですか、それともドメインロジックですか?
DDDを使用してフォームをモデリングするとします。フォームには特定の種類のビジネスルールが関連付けられている場合があります。おそらく、学生でない場合は収入を指定する必要があり、結婚していることを示す場合は子供をリストする必要があります。国を指定した場合は、有効な国が必要です。 この種の検証は、ドメインまたはアプリケーション層に存在しますか?私が検討していたいくつかの他の問題: Laravelなどの特定のフレームワークは、要求がコントローラーに到達する前に入力を検証できる検証ルールを提供します。そのレベルで検証が行われると、DDDが破損しますか? 国が有効かどうかを判断する場合など、通常は世界のすべての国のデータベーステーブルを照会するだけです。ただし、DDDでは、これは(私の理解から)ドメイン層で行われる可能性があります。ドメインレイヤーはDBへのアクセスを許可されていますか、または非SQL検索を使用して有効な国を決定する必要がありますか? アプリケーションとドメイン層の両方で入力を検証する必要がありますか?

3
実用面でのドメイン駆動開発とは何ですか?[閉まっている]
閉じた。この質問はより集中する必要があります。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集するだけで1つの問題に焦点を当てるように質問を更新します。 閉じた3年前。 この分野の開発者からドメイン駆動開発について聞いた。彼は、それが要件の変化に対する特効薬であるかのようにそれを話しました。 wikiを読みました。まだ明確ではありません。実用的な用語で「3D」とは何ですか?現在、UMLクラス図が時代遅れになっているのは本当に驚くべきことですか?

5
REST APIはコマンド/アクションベースのドメインにどのように適合しますか?
この記事の著者は、 時には、本質的にRESTfulではない操作をAPIで公開する必要があります。 そしてそれ APIのアクションが多すぎる場合は、RESTful原則を使用するのではなくRPCの観点で設計されているか、問題のAPIがRPCタイプモデルにより適していることを示しています。 これは、他の場所でも読んだり聞いたりしたことを反映しています。 しかし、これは非常に紛らわしいと思うので、問題をよりよく理解したいと思います。 例I:RESTインターフェースを介してVMをシャットダウンする VMのシャットダウンをモデル化するには、根本的に異なる2つの方法があると思います。それぞれの方法にはいくつかのバリエーションがありますが、ここでは最も基本的な違いに集中しましょう。 1.リソースの状態プロパティにパッチを適用します PATCH /api/virtualmachines/42 Content-Type:application/json { "state": "shutting down" } (または、PUTサブリソース上/api/virtualmachines/42/state。) VMはバックグラウンドでシャットダウンし、シャットダウンが成功するかどうかに応じて、後のある時点で状態が「電源オフ」で内部的に更新される可能性があります。 2.リソースのアクションプロパティのPUTまたはPOST PUT /api/virtualmachines/42/actions Content-Type:application/json { "type": "shutdown" } 結果は、最初の例とまったく同じです。状態はすぐに「シャットダウン」に更新され、最終的には「電源オフ」に更新されます。 どちらのデザインもRESTfulですか? どちらのデザインが優れていますか? 例II:CQRS 複数の集約の更新につながる可能性のある、または具体的なリソースとサブリソースのCRUD操作にマッピングできない「アクション」(別名コマンド)が多数あるCQRSドメインがある場合はどうなりますか? 具体例で可能な限り多くのコマンドを具体的なリソースで作成または更新し(例Iの最初のアプローチに従って)、残りの部分に「アクションエンドポイント」を使用してみてください。 または、すべてのコマンドをアクションエンドポイントにマッピングする必要があります(例Iの2番目のアプローチのように)。 どこで線を引きますか?設計のRESTful性が低下するのはいつですか? CQRSモデルは、APIのようなRPCにより適していますか? 上記の引用テキストによると、私が理解しているとおりです。 私の多くの質問からわかるように、このトピックについて少し混乱しています。それをよりよく理解するのを手伝ってもらえますか?

2
DDD集計のシリアル化のベストプラクティス
DDDによると、ドメインロジックは、シリアル化、オブジェクトリレーショナルマッピングなどの技術的な問題で汚染されるべきではありません。 それでは、ゲッターとセッターを介して公開することなく、集計の状態をどのようにシリアル化またはマッピングしますか?リポジトリの実装など、多くの例を見てきましたが、実際にはすべて、マッピングのエンティティと値オブジェクトのパブリックアクセサーに依存していました。 リフレクションを使用してパブリックアクセサーを回避することもできますが、これらのドメインオブジェクトはIMOで暗黙的にシリアル化の問題に依存します。たとえば、シリアル化/マッピングの設定を調整しないと、プライベートフィールドの名前を変更したり削除したりできませんでした。そのため、代わりにドメインロジックに焦点を当てる必要があるシリアル化を検討する必要があります。 ここで従うべき最良の妥協点は何ですか?パブリックアクセサーと一緒に住んでいますが、マッピングコード以外には使用しないでください。または、明らかな何かを見逃しただけですか? 私は、DDDドメインオブジェクト(エンティティと値オブジェクトで構成される集約)の状態をシリアル化することに明確に興味があります。これは、一般的なシリアル化や、ステートレスサービスが単純なデータコンテナオブジェクトで動作するトランザクションスクリプトシナリオではありません。

5
「セッターなし」の世界での単体テスト
私は自分自身をDDDの専門家とは考えていませんが、ソリューションアーキテクトとして、可能な限りベストプラクティスを適用しようとしています。私は、DDDのノー(パブリック)セッター「スタイル」の賛否両論について多くの議論があることを知っており、議論の両側を見ることができます。私の問題は、スキル、知識、経験が非常に多様なチームで働いているということです。つまり、すべての開発者が「正しい」方法で作業することを信頼することはできません。たとえば、オブジェクトの内部状態の変更がメソッドによって実行されるがパブリックプロパティセッターを提供するようにドメインオブジェクトが設計されている場合、誰かがメソッドを呼び出す代わりにプロパティを設定することは避けられません。この例を使用します。 public class MyClass { public Boolean IsPublished { get { return PublishDate != null; } } public DateTime? PublishDate { get; set; } public void Publish() { if (IsPublished) throw new InvalidOperationException("Already published."); PublishDate = DateTime.Today; Raise(new PublishedEvent()); } } 私の解決策は、プロパティセッターをプライベートにすることです。これは、オブジェクトをハイドレートするために使用しているORMがリフレクションを使用してプライベートセッターにアクセスできるためです。ただし、単体テストを作成しようとすると問題が発生します。たとえば、再発行できないという要件を検証する単体テストを作成する場合、オブジェクトが既に発行されていることを示す必要があります。確かに2回Publishを呼び出すことでこれを行うことができますが、私のテストでは、最初の呼び出しでPublishが正しく実装されていると想定しています。それは少し臭いようです。 次のコードを使用して、シナリオをもう少し現実的にしましょう。 public class Document { public Document(String title) …

2
ドメイン駆動設計-エンティティ問題の外部依存関係
Domain-Driven-Designを開始したいのですが、開始する前に解決したい問題がいくつかあります:) グループとユーザーがあり、ユーザーがグループに参加したい場合、groupsService.AddUserToGroup(group, user)メソッドを呼び出していると想像してください。DDDで行う必要がgroup.JoinUser(user)あります。 ユーザーを追加するための検証ルールがある場合、またはユーザーがグループに追加されたときに外部タスクを開始する必要がある場合に問題が発生します。これらのタスクを実行すると、エンティティが外部依存関係を持つことになります。 例としては、ユーザーが最大3グループまでしか参加できないという制限があります。これを検証するには、group.JoinUserメソッド内からのDB呼び出しが必要です。 しかし、エンティティがいくつかの外部サービス/クラスに依存しているという事実は、私にはそれほど自然で「自然」ではないようです。 DDDでこれに対処する適切な方法は何ですか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.