web-dev-qa-db-ja.com

DDD-アグリゲート間のドメインモデリングの関連付け

DDDの練習中にシナリオをモデル化しようとすると、少し精神的な障害が発生します。

問題は、集計ルートであると見なす2つのエンティティにあるようです。これらの集合ルートは、それぞれの境界コンテキストでの集合ルートになると思います。

基本的に、私はこのシナリオに適用する複雑なルールを持っています。私は次のシナリオでこれを単純化しようとしました:

シナリオ

シナリオは製品を取ることです。このプロデュースは、デザインチームによってさまざまな次元を持つデザインコンテキストにまとめられます。

その後、生産ラインで組み立てられます。製品はバッチで存在します。

その後、製品が組み立てられると、検査官による品質管理検査が行われます。

インスペクターは、バッチ内の多数の製品をランダムに選択し、品質管理(QC)チェックに合格するかどうかを判断します。の線に沿ったものは、最小範囲と最大範囲の間の製品幅です。また、製品の目視検査も行いました。

検査官は、さまざまなチェックを実行する資格を持っている必要があります。したがって、彼は特定の日付まで有効な有効なVisual QC証明書を持っている必要があります-資格を再取得する前に。ディメンションチェックを実行するには、有効なDimension QC証明書が必要です。

1つのインスペクターが視覚的なチェックを行い、別のインスペクターが寸法のチェックを行う場合があります。製品がQCに合格するためには、視覚チェックと寸法チェックに合格する必要があります。チェックの結果は、合格または不合格です。

DDD戦術パターンの適用

これで、ドメインモデルのコードを記述できるようになりました。 DDD戦略がうまく適用されていると仮定すると、私は現在次のようにしています:

境界コンテキストの設計

  • 製品バッチ集計ルート
  • 製品エンティティ

資格制限付きコンテキスト

  • インスペクター集計ルート
  • 検査証明書エンティティ

品質管理境界コンテキスト

これは一見、製品/製品バッチとインスペクターの概念を統合する必要があるようです。

Vaughn Vernonの赤い本や、Udi Dahanの Many to Many を含む無数のオンライン記事を読み続けています。

特定のアグリゲートルートが使用されていますか?シナリオにUdiの理論を適用してみたので、インスペクターが集約ルートであるように感じます。

しかし、Aggregateを全体として扱う必要がある場合、それはすべての子データをロードする必要があることを意味しますか?初日以降のすべての検査と初日以降のすべての資格であれば、それはかなりのオーバーヘッドになります。

したがって、モデルをすばやくモックアップして、いくつかの明確さを追加しようとします-原始的なことにこだわった、実際には表現力がなく、わずかに貧弱なアプローチで、いくつかのコンテキストをすばやく表示します。

public class InspectorAggregateRoot
{
    public Guid Id { get; private set; }

    public List<Qualification> Qualifications { get; private set; }

    public List<Inspection> Inspections { get; private set; }

    public void PerformInspection(Product product, InspectionType type, bool hasPassed)
    {
        if (!IsInspectorQualified())
        {
            throw new InvalidOperationException("Inspector is not qualified");
        }

        Inspections.Add(new Inspection
        {
            InspectionDate = DateTime.Now,
            InspectionType = type,
            Pass = hasPassed,
            ProductId = product.Id
        });
    }

    private bool IsInspectorQualified()
    {
        // check inspectors qualifications
        return true;
    }
}

public class Inspection
{
    public Guid ProductId { get; set; }

    public InspectionType InspectionType { get; set; }

    public DateTime InspectionDate { get; set; }

    public bool Pass { get; set; }
}

public enum InspectionType
{
    Visual,
    Dimension
}

public class Product
{
    public Guid Id { get; set; }
    public int Height { get; set; }
    public int Width { get; set; }
    public int Length { get; set; }
}

public class Qualification
{
    public InspectionType InspectionType { get; private set; }

    public DateTime ValidTo { get; set; }
}

[〜#〜]注[〜#〜]:はい私は意図的にリストの更新を省略しましたが、これは簡単なので、貧血の部分について気になりませんモデリングシナリオを強調するためにダーティ-これはまだValueオブジェクトについてではありません-まだ。

物事を正しくする

もちろん、私は初めて物事を正しくするつもりはありません。しかし、これは私が複雑なシステムのDDDを本当に信じているので、既存のシステムを書き換える私です。前のものは.NET Entity Frameworkソリューションであり、本質的にはEntity Frameworkを使用して駆動され、ビジネスロジックはアプリケーション全体に散在していました。恐ろしいBBoMといくつかのスパゲッティコード-​​単体テストは困難です。私は、ある程度慣れているドメインにDDD学習を適用することにしました。戦略を正しくし、経験を積むために必要な戦術パターンを適用しようとしています。

私はすでに数えきれないほどのクラスの反復を経験しました。値型のニースセットがあります。しかし、ユースケース/プロセスを一緒に接着するときがきました。

したがって、ここで重要なのは、製品の検査プロセスを「モデル化」する方法です。

質問が多すぎますが、これへのアプローチと最善の方法を見つけることについて話し合いたいと思います。

頭に浮かぶ質問は次のとおりです。

  • 私が示した総合的なアプローチはシナリオに適していますか?
  • ドメインサービスの方が適していますか?
  • 何かが起こったと私が言っているので、たぶんドメインイベントはより適していますか?
  • 思考のパフォーマンス-アグリゲートはシナリオのすべての子をロードする必要がありますか?
  • Productが1つのBounded Contextを作成し、私が例で示したより多くのプロパティを使用して、私が理解しているように、Bounded Contextでも消費されている場合、それはそのBounded Contextからの別のビューですが、異なる方法で表現されますが、必要なデータを定義するだけで問題ありません。

その他の考えは次のとおりです。

  • インスペクターは100の資格を持っている可能性があります(つまり、例にないさまざまなインスペクションタイプ)
  • バッチには何千もの製品があるかもしれません
  • システムの存続期間中は、多くのバッチが存在します。
4
Andez

たくさんの質問ですが、いくつかのことは明らかです

  • インスペクターにインスペクションを含めることはできません。

これらは時間とともに増加するため、遅かれ早かれ、メモリにロードするには多すぎます。それらを、使用方法に適合する集約ルートに移動する必要があります。おそらくバッチ?おそらく、特定の割合の検査が失敗するとバッチが失敗し、バッチごとの検査の数には自然な制限があります。

  • インスペクションがなければ、インスペクターは事実上ドメインサービスです。

検査結果を返す無限の製品ストリームを検査している間、その状態は一定のままです。

  • 製品およびバッチごとの検査の集計チェックが必要です。

すなわち。製品の両方に合格するために異なるタイプの2つの検査が必要な場合は、選択した製品ごとに両方のチェックが行われたことを確認する必要があります

そして。特定の数の製品が検査に失敗した場合にバッチを失敗させる必要がある場合、これらの検査された製品をバッチごとに収集する必要があります。

これには何らかのBatchオブジェクトまたは何らかのサービスが必要であるように思えます

4
Ewan