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

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

3
DDDによるトランザクションの整合性の確保
私はDDDから始めて、国境を越えた一貫性を確保するために集約ルートが使用されることを理解しています。1つのアプリケーションサービスで複数の集計を変更しないでください。 ただし、次のような場合の対処方法を教えてください。 Productsという集約ルートがあります。 グループと呼ばれる集約ルートもあります。 どちらにもIDがあり、個別に編集できます。 複数の製品が同じグループを指すことができます。 製品のグループを変更できるアプリケーションサービスがあります。 ProductService.ChangeProductGroup(string productId, string groupId) チェックグループが存在する リポジトリから製品を取得する グループを設定する 製品をリポジトリに書き戻す グループを削除できるアプリケーションサービスもあります。 GroupService.DeleteGroup(string groupId) 1. groupIdが提供されたgroupIdに設定されているリポジトリから製品を取得し、カウントが0または中止であることを確認します2.グループリポジトリからグループを削除します3.変更を保存します 私の質問は、次のシナリオです。 ProductService.ChangeProductGroupで、グループが存在することを確認し(存在する場合)、この確認の直後に、別のユーザーが(他のGroupService.DeleteGroupを介して)productGroupを削除します。この場合、削除されたばかりの製品への参照を設定しますか? これは、別のドメイン設計を使用する必要がある(必要に応じて追加の要素を追加する)か、トランザクションを使用する必要があるという点で、私の設計の欠陥ですか?

2
DDDを実行するときにエンティティと値オブジェクトをモックする必要がありますか?
読んだ後、いくつかの 記事についてNewableを対注射のオブジェクトとどのようにこれらの概念は、DDDのサービス、エンティティと値オブジェクトに関連し、私は特に私のユニットテストで私のコードでnewablesの使用に関するいくつかの疑問が残りました。 Newableの主な候補は、EntitiesオブジェクトとValueオブジェクトでした。つまり、これらの依存関係を他のオブジェクトに注入する代わりにnew、これらのオブジェクトのインスタンスだけを作成して、コードで直接使用する必要があります。 ただし、適切なDDDプラクティスでは、エンティティと値オブジェクトに適切であると見なされた場合に責任を割り当てることを推奨しています。そのため、エンティティと値オブジェクトには、深刻なビジネスロジックが含まれなくなります。 ここで、サービスがエンティティまたは値オブジェクトで動作する場合、エンティティまたは値オブジェクトをモックしてサービスにモックを渡す必要があります(モックには、interface推奨されているように見える値オブジェクトまたはエンティティのが必要です)? またはnew、エンティティ/値オブジェクトだけを具体的な実装をサービスに渡して、1つのユニットのみをテストするというユニットテストの原則に違反する必要がありますか?

3
DDDのプレゼンテーションVSアプリケーション層
ドメインドリブンデザインのプレゼンテーションレイヤーとアプリケーションレイヤーの間に明確な線を引くことができません。 コントローラ、ビュー、レイアウト、JavaScript、CSSファイルはどこに配置すればよいですか? アプリケーション層かプレゼンテーション層か? そして、それらが同じレイヤーですべて一緒に行く場合、何が他のレイヤーを含みますか?空っぽですか?

3
DDDおよび値オブジェクト。変更可能な値オブジェクトは非Aggrの良い候補です。ルートエンティティ?
ここで少し問題があります 値オブジェクトを持つエンティティーがあります。問題ない。新しい値の値オブジェクトを置き換え、nhibernateが新しい値を挿入し、古い値を孤立させてから削除します。わかりました、それは問題です。 被保険者は私のドメイン内のエンティティです。彼はアドレス(値オブジェクト)のコレクションを持っています。アドレスの1つはMailingAddressです。郵送先住所を更新したい場合、たとえば郵便番号が間違っていたとしましょう。エヴァンス氏の教えに従い、古いオブジェクトは不変なので、新しいオブジェクトに置き換える必要があります(値オブジェクトは正しいですか?)。 ただし、そのアドレスのPKはMailingHistoryテーブルのFKであるため、行を削除したくありません。したがって、エヴァンス氏の教義に従って、私たちはここでかなりねじ込まれています。私がエンティティをアドレス指定しない限り、それを「置き換える」必要はなく、単に古き良き時代のようにその郵便番号のメンバーを更新するだけです。 この場合、私に何を提案しますか?私の見たところ、ValueObjectsは、データベーステーブルの列(nhibernateのコンポーネント)のグループをカプセル化する場合にのみ役立ちます。データベースに永続IDがあるものはすべて、エンティティ(必ずしも集約ルートではない)にすることをお勧めします。これにより、特に深くネストされたオブジェクトの場合は、オブジェクトグラフ全体を再作成せずにメンバーを更新できます。 同意しますか?エバンス氏は可変値オブジェクトを持つことを許可されていますか?または、可変値オブジェクトはエンティティの候補ですか? ありがとう

11
OOPで画像のサイズを変更できる必要がありますか?
私はImageエンティティを持つアプリを作成していますが、各タスクの責任を決定するのにすでに苦労しています。 最初に私はImageクラスを持っています。パス、幅、その他の属性があります。 次にImageRepository、単一のテスト済みメソッドで画像を取得するためのクラスを作成しましたfindAllImagesWithoutThumbnail()。 しかし今、私もできるようにする必要がありますcreateThumbnail()。誰がそれに対処すべきですか?ImageManagerアプリ固有のクラスになるクラスを考えていました(選択したサードパーティの画像操作の再利用可能なコンポーネントもあり、私はホイールを再発明していません)。 それとも、Imageサイズ変更自体を行うには0Kでしょうか?または聞かせてImageRepositoryとImageManager同じクラスで? どう思いますか?

2
DDDについて言及する場合の「ドメイン」の意味
駆動設計/開発に関してドメインという言葉は何を意味しますか? 意味論や学術的定義の観点からではなく、プロセスや哲学をどのように修正するかという観点からですか? 私は投稿を読んでいました:https : //softwareengineering.stackexchange.com/questions/57828/your-software-problem-solution-approach 私はこの流行語DDDに出くわし、それが何を意味するのか本当に知りませんでした。

3
計算された値と単純な読み取り-ドメイン主導の設計の悩​​みの種!
私が絶えず直面している問題は、データストアに対して効率的に機能しながら、ドメインロジックによって駆動される計算値を処理する方法です。 例: リポジトリからサービスを介して製品のリストを返しています。このリストは、クライアントが送信したリクエストDTOからのページネーション情報によって制限されます。さらに、DTOはソートパラメータ(クライアントフレンドリーな列挙型)を指定します。 単純なシナリオでは、すべてがうまく機能します。サービスはページングとソートの式をリポジトリに送信し、リポジトリは効率的なクエリをDBに発行します。 ただし、ドメインモデルからメモリに生成された値を並べ替える必要がある場合は、すべてが機能しなくなります。たとえば、Productクラスには、ビジネスロジックに基づいてブール値を返すIsExpired()メソッドがあります。今、私はレポレベルでソートおよびページングすることはできません-それはすべてメモリ内で行われ(非効率的)であり、私のサービスはこれらのパラメーターをレポに発行するタイミングとソート/ページングを実行するタイミングの複雑さを知る必要があります自体。 私にとって意味があると思われる唯一のパターンは、エンティティの状態をdbに格納することです(IsExpired()を読み取り専用フィールドにして、保存する前にドメインロジックを介して更新します)。このロジックを別の「読み取りモデル/ dto」と「レポート」リポジトリに分離すると、モデルが必要以上に貧弱になります。 ところで、このような計算で私が見たすべての例は、実際にはインメモリ処理に頼っており、長期的には効率がはるかに低いという事実を無視しているようです。多分私は時期尚早に最適化していますが、それはちょうど私と一緒に座っていません。 DDDを含むほぼすべてのプロジェクトで一般的であると確信しているので、他の人がこれをどのように処理したかを聞いてみたいです。

1
フィルタリングロジックは、リポジトリまたはサービス内にある必要がありますか?
私は次のことを考えています。エンティティを検索するためのフィルタリング機能が必要なシステムを構築しているとします。たとえば、エンティティをリストするテーブルにフィルタリングを適用して何かを見つけたり、それを使用してフィルタリングされたセットに関するレポートを生成したりすることができます。 重要なのは、フィルタリングロジックをどこかに置く必要があるということです。これを行う1つの悪い方法は、必要に応じてフィルタリングロジックを複製することです。私はそれを一度やったことがあり、それはひどい考えです。 一方、Filter(FilteringOptions filteringOptions)フィルタリング操作を実行してエンティティのフィルタリングされたリストを返すように設計されたようなメソッドがあるはずです。 今、私見、フィルタリングロジックは一種のビジネスロジックです。ビジネスエキスパートは、フィルタリングがどのように行われるか、何がどのようにフィルタリングされるかを知っている人です。そのため、フィルタリングロジックはドメインレイヤーに配置する必要があります。 これを行うための2つのオプションが見つかりました。その特定のエンティティに対応するリポジトリにフィルタリングメソッドを埋め込むか、またはEntityNameSearchServiceリポジトリを使用してフィルタリングを実行するようなドメインサービスを作成します。 どちらがより良い方法であるか私はまだ混乱しています。では、DDDを適切に使用しようとしている場合、このフィルタリングロジックはどこにあるべきでしょうか。リポジトリまたは別のサービスで?

2
ゼロ引数コンストラクターと常に有効なエンティティ
私は最近、Always Validドメインエンティティについて多くの読書をしました。エンティティが常に有効であることを保証するために、私は次のことを行う必要があると信じるようになりました。 1)ここで説明されているように、プリミティブな強迫観念を取り除き、値オブジェクトコンストラクターに検証/ドメインルールを配置します:https : //enterprisecraftsmanship.com/2016/09/13/validation-and-ddd/。2)ここで説明されているように、検証またはドメインルールをエンティティまたはプロパティセッターのコンストラクタに配置します:http ://gorodinski.com/blog/2012/05/19/validation-in-domain-driven-design-ddd/ 。 ただし、次に、https://github.com/gregoryyoung/mrなどのいくつかのオープンソースプロジェクトを調べます。私が理解していることから、このプロジェクトの作成者は常に有効なドメインモデルの擁護者ですが、それでもInventoryItemクラス(https://github.com/gregoryyoung/mr/blob/master/SimpleCQRS/Domain.cs)を調べます。私はこれを行うことができることに気づきました: InventoryItem inventoryItem = new InventoryItem(); またはこれ: InventoryItem inventoryItem2 = new InventoryItem(Guid.Empty,null); 私の考えでは、これはエンティティが無効な状態で初期化されることを意味します。これは、私が最近見た他のすべてのオープンソースプロジェクトにも当てはまるようです。たとえば、次のプロジェクトです。https://github.com/dcomartin/DDD-CQRS-ES-Example/blob/master/src/Domain /Customer.cs。 これらのオープンソースプロジェクト(https://martinfowler.com/bliki/ContextualValidation.html)にコンテキスト検証があることに気づきました。また、ドメインモデルにマップする場合、ORMにはデフォルトの空のコンストラクターが必要であることも理解しています。 ドメインオブジェクトは、引数なしのコンストラクタを使用してデフォルト値で初期化されている/空/ null値で初期化されている場合、有効な状態ですか?

1
DDDのレイヤー間の通信
DDDの文献を読んで、次のレイヤーを思いつきました。 Application アウトサイダーワールド(コントローラ、クローンなど) Application Services(またはUseCases)-複数のドメインサービスまたはインフラストラクチャサービスを調整します。それらはから呼び出されOutside Worldます。彼らは何をしなければならないか知っています Domain Services -物事がどのように行われるかが含まれています(リポジトリインターフェイスに依存) 質問:レイヤー間で通信するためのベストプラクティスはありますか? 私が知っていること:- Application services公開する「必要なデータ」とトランザクションの「成功」の一部(警告、エラー、情報)をApplication Service返す必要があります- 返すデータは、そこから収集しDomain ServicesたりInfrastructure Services、収集したりする必要があります。 Controller <-> Application Service <-> Domain Service <-> Infrastructure Service これらは私の曖昧な考えの一部です: すべてのメソッドにApplication Serviceは、「リクエスト」をパラメータとして含む特定のDTOが必要ですか?同様にAddItemToCardCommandDto(必要なすべてのデータをカプセル化していること)。and やorのResultObjectようなメソッドが2つしかないジェネリックはどうですか?getResulthasErrorrsgetMessages DomainServiceデータとエラーをどのように返す必要がありますか?例外でエラーを返す必要がありますか?Bussines Validation DomainServicesはビジネスルールの一部であるため、呼び出す必要があるため、これは奇妙に思われます。

2
「その他」の集合体の状態をどこで検証する必要がありますか?
シナリオ: 顧客が注文し、製品を受け取った後、注文プロセスに関するフィードバックを提供します。 次の集計ルートを想定します。 お客様 注文 フィードバック ビジネスルールは次のとおりです。 顧客は自分の注文についてのみフィードバックを提供でき、他の人のフィードバックは提供できません。 顧客は、注文に対する支払いが済んでいる場合にのみフィードバックを提供できます。 class Feedback { public function __construct($feedbackId, Customer $customer, Order $order, $content) { if ($customer->customerId() != $order->customerId()) { // Error } if (!$order->isPaid()) { // Error } $this->feedbackId = $feedbackId; $this->customerId = $customerId; $this->orderId = $orderId; $this->content = $content; } } ここで、企業が新しいルールを望んでいると想定します。 …

2
DDD:再利用可能なモジュールとサービスタイプの区別(ドメイン、インフラストラクチャ、アプリケーション)の作成
したがって、「Vaughn Vernonによるドメイン駆動設計の実装」を読んだ後、コアドメインの概念と思われるものを個別のモジュールに分離することにより、再利用性を高めるためにコードをリファクタリングすることにしました。 各モジュールには、ドメイン、インフラストラクチャ、アプリケーション/プレゼンテーションレイヤーを含む独自のアーキテクチャレイヤーのセットが含まれています(ヴォーンの推奨に従って、アプリケーションレイヤーの責任をルート、MVCコントローラー+テンプレートに存在するテンプレートからさらに分離することにしましたプレゼンテーション層)。 これらの各レイヤーを独自のパッケージ内に配置することにしました。各パッケージは、その下のレイヤーを依存関係として参照しています。つまり、プレゼンテーション層はアプリケーション層に依存し、アプリケーションはインフラストラクチャに依存します。リポジトリはドメインの一部であるため、各リポジトリインターフェースはドメイン層/パッケージ内に存在し、実装はインフラストラクチャ層/パッケージ(Doctrine 、など)。 この方法でコードを再構築することで、アプリケーションレイヤーをスワップアウトし、複数のWebアプリケーション間でドメインを再利用できることを願っています。 最終的にコードは再び形を整え始めているように見えますが、それでも私を混乱させるのは、アプリケーション、インフラストラクチャ、ドメインサービスのこの違いです。 ドメインサービスの一般的な例の1つは、パスワードのハッシュに使用するものです。ユーザーエンティティは、ユーザーの資格情報を格納するために使用される可能性のあるさまざまなハッシュアルゴリズムに関与する必要がないため、これはSRPの観点からは理にかなっています。 そのことを念頭に置いて、私はこの新しいドメインサービスを私のリポジトリと同じように扱いました。ドメインでインターフェースを定義し、実装をインフラストラクチャ層に任せることにより。しかし、私は今、アプリケーションサービスで何をすべきかについて考えています。 現在のところ、各エンティティには独自のアプリケーションサービスがあります。つまり、ユーザーエンティティにはアプリケーション層内にUserServiceがあります。この場合のUserServiceは、プリミティブデータ型の解析と一般的なユースケース「UserService :: CreateUser(string name、string email、etc):User」の処理を担当します。 私が気になるのは、アプリケーション層を交換することにした場合、複数のアプリケーションにわたってこのロジックを再実装する必要があるという事実です。だから私はこれが私の次のいくつかの質問につながると思います: ドメインサービスは、インフラストラクチャレイヤーとモデル間の抽象化レイヤーを提供するために存在する単なるインターフェイスですか?例:リポジトリ+ HashingServicesなど 私はこのようなアプリケーションサービスを持っていると述べました: Access / Application / Services / UserService :: CreateUser(string name、string email、etc):User メソッドシグネチャは、プリミティブデータ型の引数を受け入れ、新しいユーザーエンティティ(DTOではない!)を返します。 これは、ドメインレイヤー内で定義されたいくつかのインターフェイスの実装としてインフラストラクチャレイヤーに属しますか、それともプリミティブデータ型の引数などにより、実際にはアプリケーションレイヤーがより適切ですか? 例: Access/Domain/Services/UserServiceInterface そして Access/Infrastructure/Services/UserService implements UserServiceInterface 個別のモジュールが一方向の関係をどのように処理するか。モジュールAは、モジュールBのアプリケーションレイヤー(現在行っているように)またはインフラストラクチャの実装(個別のインターフェイスを介して)を参照する必要がありますか? アプリケーション層サービスには別のインターフェースが必要ですか?答えが「はい」の場合、それらはどこに配置する必要がありますか?

7
「オブジェクトが特定の状態にある場合にのみ許可されるオブジェクトの操作」の設計パターン
例えば: まだレビューまたは承認されていない求人応募のみを更新できます。言い換えれば、人は、HRがレビューを開始するまで、またはすでに承認されるまで、ジョブアプライアンスフォームを更新できます。 したがって、求人応募は次の4つの状態になります。 APPLIED(初期状態)、IN_REVIEW、APPROVED、DECLINED どうすればこのような動作を実現できますか? 確かに、Applicationクラスにupdate()メソッドを記述し、アプリケーションの状態を確認し、アプリケーションが必要な状態でない場合は何もしないか、例外をスローすることができます しかし、この種のコードは、そのようなルールが存在することを明らかにしていません。それにより、だれでもupdate()メソッドを呼び出すことができ、クライアントが失敗した後にのみ、そのような操作が許可されなかったことがわかります。したがって、クライアントはそのような試みが失敗する可能性があることを認識する必要があるため、注意が必要です。クライアントがそのようなことを認識していることは、ロジックが外部にリークしていることも意味します。 状態ごとに異なるクラス(ApprovedApplicationなど)を作成して、許可されたクラスにのみ許可された操作を実行してみましたが、この種のアプローチも間違っているように感じます。 そのような振る舞いを実装するための公式の設計パターン、または単純なコードはありますか?

1
本当にサブドメインとは何ですか?
ドメイン駆動設計(DDD)を研究する際に、サブドメインの概念に出くわしましたが、まだ理解していないと思います。これについて私の最初の理解は、サブドメインがアプリケーションのドメインのサブセットであるということでした。言い換えれば、それは問題空間のパーティションです。サブドメインには3つのタイプがあると読みました。 コアサブドメイン サポートするサブドメイン 汎用サブドメイン。 私の理解はこのようなものでした。アプリケーションのドメインを選択しましたが、それは非常に複雑です。次に、それを見て、それをより単純な部分に分割する方法を見つけます。その一部はコアサブドメインであり、一部はサポートするものであり、その他は一般的なものです。 詳細情報を検索したところ、別のことを言っている人が見つかりました。コアサブドメインが1つだけ存在し、いくつかの汎用サブドメインがあり、サポートサブドメインがまったくないことです。 だから私の質問は: 本当にサブドメインとは何ですか?私の最初の理解は正しいものですか、それとも私が読んだ2番目のものですか? このサブドメインの考え方はどのように役立ちますか? サブドメインを識別するための良い基準は何ですか?このアイデアをより有効に活用するためにサブドメインを決定するとき、何を念頭に置く必要がありますか? 編集:もう少し検索すると、次のことがわかりました: eコマースシステムについて考えてみましょう。最初は、それがショッピングコンテキストのアプリケーションであることがわかります。さらに詳しく見ると、在庫、配送、アカウントなど、他のコンテキストもあることがわかります。 これは、私が最初にサブドメインだと思ったものです。ドメイン(ショッピングドメイン)を選択し、それをより単純なサブドメイン(在庫、配送、アカウントなど)に分割します。しかし、問題のテキストでは、彼らはこれらを文脈と呼んでいます。私の以前の理解はサブドメインではなくコンテキストですか? このサイトで、サブドメインと制限付きコンテキストの違いについて1つの質問を見つけました。答えは、サブドメインは問題空間のパーティションであり、コンテキストは解空間のパーティションであると述べています。ただし、ショッピングコンテキストを在庫、配送、アカウントなどに分離することは、概念的な区分ではありません。つまり、解空間ではなく問題空間にありますか?

2
Vernonによる「DDDの実装」:値オブジェクトかどうか?
この本の382ページに、(エンティティの)ルートの下で、値オブジェクトを集計で使用することについて説明している箇所があります。Product他の値に加えて、エンティティのSet<ProductBacklogItem>コレクションが含まれている例があります。 さて、バーノンはProductBacklogItemエンティティが値オブジェクトではなく、なぜであるかを説明しようとします: ProductBacklogItemが値ではなくエンティティとしてモデル化されるのには、十分な理由があります。値オブジェクト(6)で説明したように、バッキングデータベースはHibernateを介して使用されるため、値のコレクションをデータベースエンティティとしてモデル化する必要があります。要素のいずれかを並べ替えると、かなりの数、またはすべてのProductBacklogItemインスタンスが削除されて置き換えられる可能性があります。これは、インフラストラクチャに大きなオーバーヘッドを引き起こす傾向があります。エンティティーとして、製品所有者が必要とする頻度で、すべてのコレクション要素にわたって順序付け属性を変更できます。ただし、MySQLでのHibernateの使用からKey-Valueストアに切り替える場合は、代わりにProductBacklogItemをValueタイプに簡単に変更できます。Key-Valueまたはドキュメントストアを使用する場合、 リポジトリの実装で、モデルがエンティティオブジェクトまたは値オブジェクトになるかどうかを判断する理由がわかりません。Key-Valueストアに行く場合でも、彼が話している順序が残っている可能性があります。 これは理にかなっていると思いますか?

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