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

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

2
DDD:ルートアグリゲートが別のルートアグリゲートへの参照を保持するのは正しいですか?
ドメイン駆動型設計(DDD)に従う場合、たまたま別のアグリゲートのルートエンティティである内部エンティティへの参照をルートアグリゲートが保持するのは正しいですか? 私はこれが正しいとは思わない、主にブルーブックのこのルールのため: AGGREGATE境界の外側にあるものは、ルートENTITYを除き、内側にあるものへの参照を保持できません。ルートENTITYは、内部ENTITIESへの参照を他のオブジェクトに渡すことができますが、それらのオブジェクトは一時的にのみそれらを使用でき、参照を保持することはできません。ルートはVALUE OBJECTのコピーを別のオブジェクトに渡すことができますが、それがどうなるかは問題ではありません。これは単なるVALUEであり、AGGREGATEとの関連付けがなくなるためです。 ルートアグリゲートが別のルートアグリゲートへの参照を保持している場合、前者の境界に違反しており、アグリゲートの概念全体が破損しているため、ルートアグリゲートが別のルートアグリゲートへの参照を保持する必要があるように見える場合は、別のエンティティを作成するには、おそらく他のルートエンティティと同じメンバーの一部を共有しますが、この本の他のルールが示すように、グローバルアイデンティティはありません。 ルートエンティティにはグローバルアイデンティティがあります。境界内のエンティティには、AGGREGATE内でのみ一意のローカルIDがあります。 これは正しい方法だと思いますが、それは反復的で冗長であると感じるので(DDDのコンテキストを取り除いて、純粋なOOPで)、フィードバックを求めています。

2
DDDの実装:ユーザーと権限
私は、ドメイン駆動設計の原則を把握しようとする小さなアプリケーションに取り組んでいます。成功した場合、これは大規模プロジェクトのパイロットになる可能性があります。「Implementing Domain-Driven Design」(Vaughn Vernon著)を読み、同様のシンプルなディスカッションフォーラムを実装しようとしています。また、githubでIDDDサンプルをチェックアウトしました。私は自分のケースにアイデンティティとアクセスを採用するのに苦労しています。背景情報をいくつかご紹介します。 私は(願わくば)ユーザーとアクセス許可のロジックを分離する背後にある理由を理解しています。それはサポートドメインであり、異なる境界コンテキストです。 コアドメインには、ユーザーはなく、作成者、モデレーターのみが存在します。これらは、サービスを使用してIDおよびアクセスコンテキストにアクセスし、受信したユーザーオブジェクトをモデレーターに変換することによって作成されます。 ドメイン操作は、関連する役割をパラメーターとして呼び出します。例: ModeratePost( ..., moderator); ドメインオブジェクトのメソッドは、指定されたモデレーターインスタンスがnullでないかどうかを確認します(IDおよびアクセスコンテキストから要求されたユーザーがモデレーターロールを持っていない場合、モデレーターインスタンスはnullになります)。 ある場合には、投稿を変更する前に追加のチェックを行います: if (forum.IsModeratedby(moderator)) 私の質問は: 後者の場合、セキュリティの懸念がコアドメインに再び溶け込んでいないのですか?以前は、本は「誰が主題を投稿できるか、またはどのような条件で許可されていますか。フォーラムは著者が今それをしていることを知る必要があります」と述べていました。 本のロールベースの実装は非常に簡単です。モデレーターがコアドメインである場合、必要なときに現在のユーザーIDをモデレーターインスタンスまたはオーサーに変換しようとします。サービスは適切なインスタンスで応答するか、ユーザーに必要なロールがない場合はnullで応答します。ただし、これをより複雑なセキュリティモデルにどのように適合させることができるかわかりません。私がパイロットをしている現在のプロジェクトには、グループ、ACLなどのかなり複雑なモデルがあります。 「投稿はその所有者または編集者のみが編集する必要があります」のようにあまり複雑ではないルールでさえ、このアプローチは破綻しているように見えます。 IdentityOrAccessコンテキストにOwnerOrEditorインスタンスを要求することは適切ではないと感じ、コアドメインではますますセキュリティ関連のクラスになります。さらに、userIdだけでなく、保護されたリソースの識別子(投稿、フォーラムなどのID)をセキュリティコンテキストに渡す必要があります。 ) コアドメインへのアクセス許可を引き出し、ドメインオブジェクトのメソッドまたはサービスでそれらをチェックすることで、最終的には、セキュリティに関する懸念をドメインに混在させることになります。 セキュリティとアクセス許可がコアドメイン自体でない限り、これらのアクセス許可関連のものはコアドメインの一部であってはならないことをどこかで読みました(そしてそれに同意する傾向があります)。上記のような単純なルールは、セキュリティをコアドメインの一部にすることを正当化しますか?

6
自律マイクロサービス、イベントキュー、およびサービス検出
私は最近マイクロサービスについて多くのことを読んでいますが、これまでに得た結論のいくつかを以下に示します(私が間違っている場合は修正してください)。 マイクロサービスアーキテクチャは、ドメイン駆動型の設計に適しています。通常、1つのMSは1つの境界付きコンテキストを表します。 マイクロサービスAがマイクロサービスBにある機能を必要とする場合、私のモデルはおそらく間違っており、AとB は実際には1つのマイクロサービス/ BCである必要があります。 マイクロサービス(直接HTTPリクエスト)間の同期通信は不良であり、マイクロサービスの目的に反し、コンポーネント間の結合を導入します。 サービス間の非同期通信が望ましい。サービスはイベントをメッセージキューに発行する必要があります。これにより、他のサービスがイベントの一部をサブスクライブおよび処理したり、コンテキストを使用してデータの一部を複製したりできます。これにより、サービスは他のサービスがダウンしていても要求を処理できますが、同期通信の場合はそうではありません。 マイクロサービスAがイベントを発行し、マイクロサービスBがそのイベントをサブスクライブし、結果として新しいイベントを生成する場合、マイクロサービスAが新しく作成されたイベントを処理するものであってはなりません。この場合、3番目のマイクロサービスを導入するか、ABマイクロサービスにAとBを組み合わせます。 マイクロサービスは実際には誤解を招く用語です。私たちは小さな文脈に努めるべきですが、そうである必要はありません。用語は「マイクロサービス」ではなく、「ジョブサービスを行うのに十分な大きさ」である必要があります。 マイクロサービスにより、システム全体を壊すことを恐れることなく、より簡単に新しい機能を導入できます。新しいサービスを導入するか、既存のサービスをリファクタリングすることで実現できます。 各マイクロサービスには、独自のデータストレージが必要です。このアーキテクチャでは、データの複製/複製が望ましい動作です。 このアーキテクチャについての私の理解を確認する以外に、質問の他の部分は主にサービスの発見に関連しています。サービスが非同期で通信しており、Amazon SQSのような中央イベントキューを使用している場合、そのようなアーキテクチャではサービスディスカバリーがその場所にないということですか? サービスは、システム内の他のサービスに関する知識を持っていてはなりません。彼らは、自分のコンテキストと、発行または購読するイベントのみを認識していますか?

2
これは、ドメイン駆動設計のRESTful Webサービスに適したVisual Studioソリューション構造ですか?
私は.NET 4.5 C#Web API RESTfulソリューションを構築していますが、ドメイン駆動設計を使用して設計されたソリューションのプロジェクトソリューションが正しいか、賢明であるか(または十分ですか)を教えてください。 ソリューションは6つのプロジェクトに分割されました。 /ベース (何にも参照されない) Webプロジェクトは、ソリューションと外部の世界との間のインターフェースを形成します。Web APIコントローラーが含まれています。要求オブジェクトから値を収集し、BizApiレイヤーに作業を依頼する以外のロジックはほとんど含まれていません。 /Biz.Api (ベースで参照]) ドメインサービスを提供し、/ Baseインターフェイスプロジェクトが/Biz.Domainプロジェクトのドメインビジネスロジックオブジェクトにアクセスできるようにします。 /Biz.Domain (Biz.Apiが参照) Biz.Apiレイヤーのドメインクラスを提供します。これらは、メモリ内のビジネスのデータを操作するメソッドを提供します。 /Dal.Db (Biz.Apiが参照) データベースリポジトリレイヤー。データベースにアクセスし、返されたデータを/ Interfacesレイヤーで定義された内部DTOにマップします。 /Dal.Services (Biz.Apiが参照) Webサービスなどの外部の依存関係にプロキシレイヤーを提供し、返されたデータを/ Interfacesプロジェクトで定義された内部DTOにマップします。 /インターフェース (上記のほとんどのプロジェクトで参照) ソリューションにデータを渡すためのDTOクラスと、IoCなどのコントラクトを定義するC#インターフェイスが含まれています。

3
集約ルートに別のARを含める必要がある場合(および含めない場合)
最初に投稿の長さについて謝罪しますが、コメントで前後に時間をかけないように、できるだけ多くの詳細を前もって伝えたいと思いました。 DDDアプローチに従ってアプリケーションを設計していますが、集約ルートに別のARを含めるべきか、それとも独立した「独立した」ARとして残すべきかを判断するためにどのようなガイダンスに従うべきか疑問に思っています。 従業員がその日のために自分で出入りできる単純なタイムクロックアプリケーションの場合を考えてみましょう。UIを使用すると、従業員IDとPINを入力できます。これらは検証され、従業員の現在の状態が取得されます。従業員が現在出勤している場合、UIには「Clock Out」ボタンが表示されます。そして、逆に、彼らが出勤していない場合、ボタンには「Clock In」と表示されます。ボタンによって実行されるアクションは、従業員の状態にも対応しています。 アプリケーションは、RESTfulサービスインターフェイスを介して公開されるバックエンドサーバーを呼び出すWebクライアントです。直感的で読み取り可能なURLを作成する最初のパスの結果、次の2つのエンドポイントが作成されました。 http://myhost/employees/{id}/clockin http://myhost/employees/{id}/clockout 注:これらは、従業員IDとPINが検証され、「ユーザー」を表す「トークン」がヘッダーで渡された後に使用されます。これは、マネージャーまたはスーパーバイザーが別の従業員に出勤または出勤できるようにする「マネージャーモード」があるためです。しかし、この議論のために、私はそれをシンプルにしようとしています。 サーバーには、APIを提供するApplicationServiceがあります。ClockInメソッドの最初のアイデアは次のようなものです。 public void ClockIn(String id) { var employee = EmployeeRepository.FindById(id); if (employee == null) throw SomeException(); employee.ClockIn(); EmployeeRepository.Save(); } これは、従業員のタイムカード情報がトランザクションのリストとして実際に維持されていることに気付くまで、非常に簡単です。つまり、ClockInまたはClockOutを呼び出すたびに、従業員の状態を直接変更するのではなく、従業員のタイムシートに新しいエントリを追加しています。従業員の現在の状態(出勤しているかどうか)は、タイムシートの最新のエントリから取得されます。 したがって、上記のコードを使用する場合、リポジトリは従業員の永続プロパティが変更されていないことを認識し、従業員のタイムシートに新しいエントリが追加されたことを認識し、データストアに挿入する必要があります。 一方(そして、ここに投稿の最終的な質問があります)、TimeSheetはAggregate Rootであり、アイデンティティ(従業員IDと期間)を持っているように見え、TimeSheet.ClockInと同じロジックを簡単に実装できます(従業員ID)。 私は2つのアプローチのメリットについて議論していることに気づき、冒頭の段落で述べたように、どのアプローチが問題により適しているかを判断するためにどの基準を評価すべきか疑問に思います。

5
厳密なTDDとDDDを組み合わせる方法
TDDは、テストによって導かれるコードの設計に関するものです。 したがって、通常、典型的なレイヤーは事前に構築されていません。それらはリファクタリング手順でわずかに表示されるはずです。 ドメイン駆動型設計には、アプリケーション層、インフラストラクチャ層、ドメイン層、永続層などの十分に確立された層を定義する多くの技術的パターンが含まれます。 DDDプロジェクトのコーディング部分をゼロから開始するには、どのように動作するのですか? DDDの技術的なパターンに適合するために、設計をテストから厳密に浮かび上がらせる必要がありますか? または、それらの空のレイヤー(アプリケーション、エンティティ/ドメインサービス、インフラストラクチャ)を作成し、TDDをそれぞれに個別に適合させる必要があります(モックを使用してレイヤー間を分離します)。

2
DDD CQRS-クエリごとおよびコマンドごとの承認
概要 CQRS / DDDの承認は、コマンド/クエリごとに実装する必要がありますか? 多かれ少なかれ厳密にDDD CQRSパターンを使用するオンラインアプリケーションを初めて開発しています。私はいくつかの問題にぶつかりましたが、それを本当に回避することはできません。 私が作成しているアプリケーションは、元帳アプリケーションで、元帳を作成できるほか、従業員など他の人が元帳を表示/編集/削除できます。元帳の作成者は、作成した元帳のアクセス権を編集できる必要があります。所有権を変更することさえできます。ドメインには、TLedgerとTUserの 2つの集約があります。 セキュリティ、認可などに関するDDD / CQRSキーワードを含む多くの投稿を読みました。それらのほとんどは、セキュリティアプリケーションを構築していない限り、認可はGeneric Subdomainであると述べました。 この場合、コアドメインは確かに、トランザクション、バランシング、アカウントに関心のあるアカウンティングドメインです。ただし、元帳へのきめ細かいアクセスを管理できる機能も必要です。これをDDD / CQRSの用語でどのように設計するのか疑問に思っています。 コマンドがユビキタス言語の一部であるということは、DDDチュートリアルの至る所で述べられています。それらは意味があります。それらは「本物」を表す具体的なアクションです。 これらのコマンドとクエリはすべて、ユーザーが「実際に」実行する実際のアクションであるため、承認の実装をこれらすべての「コマンド」および「クエリ」と組み合わせる必要がありますか?ユーザーには、たとえばTLedger.addTransaction()を実行する権限がありますが、TLedger.removeTransaction()は実行できません。または、ユーザーはクエリ「getSummaries()」を実行できますが、「getTransactions()」は実行できません。 アクセス権を決定するために、user-ledger-commandまたはuser-ledger-queryの形式で3次元マッピングが存在します。 または、切り離された方法で、「permissions」という名前がユーザーに登録されます。特定のコマンド用にマップされる許可。たとえば、権限「ManageTransactions」では、ユーザーは「AddTransaction()」、「RemoveTransaction()」などを実行できます。 権限マッピングユーザー->元帳->コマンド/クエリ パーミッションマッピングユーザー->元帳->パーミッション->コマンド/クエリ それが質問の最初の部分です。または、簡単に言えば、CQRS / DDDの承認はコマンドごとまたはクエリごとに実装する必要がありますか?または、許可をコマンドから分離する必要がありますか? 第二に、許可に基づいた認可について。ユーザーは、自分の元帳または管理が許可されている元帳の権限を管理できる必要があります。 元帳で許可管理コマンドが発生する grantPermission()、revokePermission()などのイベント/コマンド/ハンドラーをLedger集計に追加することを考えました。この場合、これらのルールの強制はコマンドハンドラーで発生します。ただし、これにはすべてのコマンドに、そのコマンドを発行したユーザーのIDを含める必要があります。次に、そのコマンドを実行する権限がそのユーザーに存在する場合、TLedgerをチェックインします。 例えば ​​: class TLedger{ function addTransactionCmdHandler(cmd){ if (!this.permissions.exist(user, 'addTransaction') throw new Error('Not Authorized'); } } ユーザーの許可管理コマンド もう1つの方法は、TUserにアクセス許可を含めることです。TUserには一連の権限があります。次に、TLedgerコマンドハンドラーでユーザーを取得し、コマンドを実行する権限があるかどうかを確認します。しかし、これには、すべてのTLedgerコマンドのTUser集計を取得する必要があります。 class TAddTransactionCmdHandler(cmd) { this.userRepository.find(cmd.userId) .then(function(user){ if …

5
DDD、Saga、およびイベントソーシング:補償アクションは、イベントストアで単に削除できますか?
上記の質問はおそらくいくつかの「何??」を発生させることを理解していますが、説明しよう: 私は、いくつかの関連する概念、基本的にはSaga-pattern(http://www.rgoarchitects.com/Files/SOAPatterns/Saga.pdf)とEvent-sourcing(A DDD-concept)に頭を包み込もうとしています。:http : //en.wikipedia.org/wiki/Domain-driven_design) まとめた良い投稿:https : //blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/ 私はすぐに質問に近づいていますが、最初にそれについて理解していることを要約しようとする必要があると思います(これは間違っている可能性がありますので、その場合は修正してください)次から始まる質問をする: Sagaパターンは、アクション(エンドユーザー、自動化など、本質的にデータを変更するもの)を指定したブローカーの一種で、そのアクションをビジネスアクティビティに分割し、これらの各アクティビティをメッセージとしてメッセージバスに送信します。次に、それをそれぞれの集約ルートに送信して処理します。 これらの集約ルートは完全に自律的に動作できます(懸念事項の分離、優れたスケーラビリティなど)。 Sagaインスタンス自体には、ビジネスロジックが含まれていません。ビジネスロジックは、アクティビティを送信する集約ルートに含まれています。佐賀に含まれる唯一の「ロジック」は「プロセス」ロジック(多くの場合Statemachineとして実装されます)で、受信したアクション(およびフォローアップイベント)に基づいて何を行うか(つまり、どのアクティビティを送信するか)を決定します Saga-patternsは、一種の分散トランザクションパターンを実装します。つまり、集約ルートの1つ(相互の存在を認識せずに自律的に動作する)の1つが失敗した場合、アクション全体をロールバックする必要があります。 これは、佐賀へのアクティビティレポートの完了時に、すべての集約ルートを持つことで実装されます。(成功とエラーの場合) すべての集約ルートが成功を返す場合、佐賀が次に何をすべきかを決定する(または完了したと判断する)場合、内部ステートマシン 失敗した場合、佐賀は、最後のアクションに参加したすべての集約ルートに対して、いわゆる補償アクション、つまり、各集約ルートが行った最後のアクションを取り消すアクションを発行します。 アクションが「プラス1票」の場合、これは単に「マイナス1票」を実行することですが、ブログポストを以前のバージョンに復元するなど、より複雑になる可能性があります。 イベントソーシング(2つを組み合わせたブログ投稿を参照)は、集約された各ルートが行う各アクティビティの結果を一元化されたイベントストアに保存することを外部化することを目的としています(このコンテキストでは変更は「イベント」と呼ばれます) このイベントストアは「真実の単一バージョン」であり、保存されたイベントを繰り返すだけで(本質的にイベントログのように)すべてのエンティティの状態を再生するために使用できます。 2つを組み合わせること(つまり、集約ルートがイベントソーシングを使用して変更を保存し、佐賀に報告する前に変更を保存する)により、多くの素晴らしい可能性が可能になります。 これを一度に把握するのは大変なので、肩から離す必要があると感じました。このコンテキスト/マインドセットが与えられます(もう一度、間違っている場合は修正してください) 質問:集約ルートが補正アクションを受信し、その集約ルートがイベントソーシングを使用した状態変更を外部委託している場合、すべての状況での補正アクションは、そのイベントストアの最後のイベントの削除だけではありません集約ルートを指定しますか?(persist-implementationが削除を許可すると仮定) それは私にとって非常に理にかなっています(そしてこの組み合わせのもう一つの大きな利点です)が、私が言ったように、これらの概念の誤った/不完全な理解に基づいてこれらの仮定をしているかもしれません。 これが長すぎないことを願っています。 ありがとう。

7
単純なドメインオブジェクトを表すプリミティブvsクラス?
domain-speciifcオブジェクトとプレーンな文字列または数字を使用する場合の一般的なガイドラインまたは経験則は何ですか? 例: 年齢階級と整数? FirstNameクラスとString? UniqueID vs String PhoneNumberクラスvs文字列vs Long? DomainNameクラスとString? ほとんどのOOP実践者は、間違いなくPhoneNumberとDomainNameの特定のクラスを言うと思います。それらを有効にするものとそれらを比較する方法に関するルールが増えると、単純なクラスをより簡単かつ安全に処理できるようになります。しかし、最初の3つについては、さらに議論があります。 私は「年齢」クラスに出会ったことはありませんが、非負でなければならないので理にかなっていると主張することができます(負の年齢について議論できることはわかっていますが、プリミティブ整数とほぼ同等である良い例です)。 文字列は「名」を表すのが一般的ですが、空の文字列は有効な文字列ですが、有効な名前ではないため、完全ではありません。通常、比較は大文字小文字を無視して行われます。空のチェック、大文字と小文字を区別しない比較などを行う方法はありますが、これを行うにはコンシューマーが必要です。 答えは環境に依存しますか?私は主に、おそらく10年以上にわたって存続し、維持されるエンタープライズ/高価値ソフトウェアに関心を持っています。 おそらく私はこれを考えすぎていますが、クラスとプリミティブのどちらを選択するかについてのルールがあるかどうかを知りたいと思います。

2
イベントソーシングでプロセスマネージャーを実装する方法
私はCQRSとイベントソーシングの概念を学ぶために、小さなサンプルアプリケーションに取り組んでいます。私が持っているBasket骨材とProduct独立して動作するはず集計を。 実装を示すための擬似コードを次に示します Basket { BasketId; OrderLines; Address; } // basket events BasketCreated { BasketId; } ItemAdded { BasketId; ProductId; Quantity } AddItemSucceeded { BasketId; ProductId; Quantity } AddItemRevoked { BasketId; ProductId; Quantity } ItemRemoved { BasketId; ProductId; Quantity } CheckedOut { BasketId; Address } Product { ProductId; Name; Price; } …

1
ユビキタス言語を文書化するには?
当社は、多くの手動のビジネスプロセス(および関連する組織の知識)を新しいエンタープライズソフトウェアに変換するプロセスを進めています。このプロジェクトは順調に進んでいますが、先に進むと、ビジネス側と開発側の両方で用語と定義に関して多くの混乱があることが明らかです。 ユビキタス言語を形成するというEvanの議論をしばらく知っていましたが、正式に文書化する必要があるのはこれが初めてです。ULの用語をどこで/どのように文書化するかを考えてみようとすると、ちょっと迷ってしまいます。 他社はユビキタス言語をどのように文書化していますか?これは単なるWikiスタイルの辞書ですか?この目的のためのツールはありますか?

4
ドメインからリポジトリにアクセスする
タスクログシステムがあるとします。タスクがログに記録されると、ユーザーはカテゴリを指定し、タスクはデフォルトで「未処理」のステータスになります。このインスタンスでは、CategoryとStatusをエンティティとして実装する必要があると想定しています。通常、私はこれをします: アプリケーション層: public class TaskService { //... public void Add(Guid categoryId, string description) { var category = _categoryRepository.GetById(categoryId); var status = _statusRepository.GetById(Constants.Status.OutstandingId); var task = Task.Create(category, status, description); _taskRepository.Save(task); } } エンティティ: public class Task { //... public static void Create(Category category, Status status, string description) { return new Task …

3
階層化アーキテクチャでの検証と承認
「検証が階層化アーキテクチャのどこに属しているのかを尋ねる別の質問ではありませんか?!?」ええ、はい、しかし、これがこの問題に対する少し異なる見解になることを願っています。 私は、検証は多くの形式を取り、コンテキストベースであり、アーキテクチャの各レベルで異なると固く信じています。これが投稿の基礎です。各レイヤーで実行される検証のタイプを識別するのに役立ちます。また、よくある質問は、承認チェックの場所です。 サンプルシナリオは、ケータリングビジネスのアプリケーションからのものです。日中定期的に、運転手は、トラックを現場から現場へ移動する間に蓄積した余分な現金をオフィスに引き入れることができます。このアプリケーションでは、ユーザーはドライバーのIDと金額を収集することにより、「キャッシュドロップ」を記録できます。関連するレイヤーを説明するスケルトンコードを次に示します。 public class CashDropApi // This is in the Service Facade Layer { [WebInvoke(Method = "POST")] public void AddCashDrop(NewCashDropContract contract) { // 1 Service.AddCashDrop(contract.Amount, contract.DriverId); } } public class CashDropService // This is the Application Service in the Domain Layer { public void AddCashDrop(Decimal amount, Int32 driverId) { …

3
ドメインドリブンデザインのドメインオブジェクトは書き込み専用である必要がありますか?
私はほぼ2年間ドメインドリブンデザインについて読んでおり、日々の仕事にいくつかの概念を慎重に導入するか、少なくともドメインドリブンデザイン内で定期的に行うことができる方法の計画を立てています。 特に、ドメインオブジェクトは書き込み目的にのみ使用されることを意図しているイベントソーシングとコマンドクエリの責任分離(CQRS)についての詳細を読んで、私が始めた結論の1つです。より明確にするために、私が読んだドキュメントの多くで人々が微妙に示唆していることは、ドメインオブジェクトがドメイン中心の操作/計算、検証を行う責任があること、そして主に永続化への道を提供するためにそこにあることを示唆しているようですリポジトリ実装内で提供されるインフラストラクチャ。状態を公開する責任を排除するため、これによりドメインモデルが大幅に簡素化される可能性があるという事実は気に入っていますが。 ドメインオブジェクトが主に書き込み専用オブジェクトとして使用されることが実際に正しい場合は、誰かに答えられることを望んでいるという疑問が生じます。 セッターを持つオブジェクト、またはオブジェクトの状態を変更するがC#のプロパティゲッターなどから状態を読み取る外部へのパブリックインターフェイスを提供しないメソッドで単体テストを実行するにはどうすればよいですか?そのオブジェクトをテスト可能にするためだけに状態を公開しても大丈夫ですか? ドメイン内で行われた計算または操作の結果を、それらを永続化せずにユーザーに表示し、ドメインのコンテキスト外の永続化ストアから結果をプルするにはどうすればよいですか?結果を表示するためだけに状態を公開しても大丈夫ですか? 唯一のプロパティゲッター(getアクセサー)はドメインでも書き込み可能なものでなければならないという経験則ですか?または、読み取り専用プロパティは読み取り専用であり、実際のドメインモデルで必要な役割を果たさないため、読み取り専用プロパティは避けるべき唯一のものであると言いますか? 関連資料: TDD、DDD、およびカプセル化

5
ドメインエンティティは単一責任の原則に違反していますか?
エンティティの単一の責任(変更する理由)は、それ自体を一意に識別することである必要があります。言い換えると、その責任を見つけられるようにすることです。 エリックエヴァンのDDDの本、ページ。93: エンティティの最も基本的な責任は、動作が明確で予測可能なように継続性を確立することです。彼らは予備にされている場合、彼らはこれを最善にします。属性や動作に焦点を当てるのではなく、Entityオブジェクトの定義を最も本質的な特性、特にそれを識別する、またはそれを検索または一致させるために一般的に使用される特性まで取り除きます。その動作に必要な概念と属性に不可欠な動作のみを追加します。 それを超えて、コアエンティティに関連付けられた他のオブジェクトへの動作と属性を削除することを検討してください。 1。 ... ENTITYオブジェクトの定義を最も本質的な特性、特にそれを識別する、またはそれを検索または一致させるために一般的に使用される特性まで取り除きます。コンセプトに不可欠な動作のみを追加します... いったんエンティティが割り当てられている固有のIDを、そのアイデンティティが確立され、私はそのような実体がするいかなる行動を必要としないと仮定しますので、そのアイデンティティを維持したりするために、それは自分自身を識別するのに役立ちます。したがって、著者が「概念に不可欠な振る舞い」findとはどのような振る舞いを参照しているのか理解できません(およびmatch 操作以外)。 2。 ... ENTITYオブジェクトの定義を最も本質的な特性、特にそれを識別する、またはそれを検索または一致させるために一般的に使用される特性まで取り除きます。...さらに、動作と属性を削除して、コアENTITYに関連付けられている他のオブジェクトを探します。 そのため、エンティティを特定するのに役立たないが、そのエンティティの固有の特性として行動を特徴付けます(つまり、characterえは犬に固有、飛行は飛行機に固有、産卵は鳥に固有です。) 。)、そのエンティティに関連付けられている他のオブジェクトに配置する必要があります(例:犬のエンティティに関連付けられているオブジェクトにbarえる動作を配置する必要があります)? 3。 それを超えて、コアENTITYに関連付けられた他のオブジェクトの動作と属性を削除してください。 a)MyEntity責任A_respをおよびにそれぞれ委任B_respします。ab ほとんどのにもかかわらずA_respとB_resp仕事をすることによって行われa、およびbインスタンス、クライアントはまだ提供されているA_respとB_resp通じMyEntityクライアントの観点から二つの責任はに属していることを意味しています、MyEntity。したがって、それはMyEntityまたA_resp、B_resp責任と責任を持っていることを意味していないので、SRPに違反していますか? B)私たちがいることを前提としていてもA_respとB_respに属していないMyEntity、MyEntityまだ責任があるAB_respオブジェクトの動作を調整するにaしてb。そうしないMyEntity違反SRPを最低でも、それは持っているので、2つの責任を一意に自身を識別し、またして- AB_resp? class MyEntity { private A a = ... private B b = ... public A GetA() { ... } public B GetB() { ... } /* coordinates operations of objects …

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