2

DDDを使用してプロジェクトをリファクタリングしていますが、あまりにも多くのエンティティを独自の集約ルートにしないことが心配です。DDD:レポーティング用に集約ルート内のエンティティへのリンクを維持する

私は、ProductOptionのリストとProductのリストを持つStoreを持っています。 ProductOptionは、いくつかによって使用することができる。Product。これらのエンティティは、Store集計によく合うようです。

その後、私は一時的にそのOrderLine Sを構築するためにProductを使用Orderを、持っている:今のところ、DDDは尊敬とルールと同様

class Order { 
    // ... 
    public function addOrderLine(Product $product, $quantity) { 
     $orderLine = new OrderLine($product, $quantity); 
     $this->orderLines->add($orderLine); 
    } 
} 

class OrderLine { 
    // ... 
    public function __construct(Product $product, $quantity) { 
     $this->productName = $product->getName(); 
     $this->basePrice = $product->getPrice(); 
     $this->quantity = $quantity; 
    } 
} 

が見えます。しかし、私は、集計のルールを破る可能性のある要件を追加したいと思います。Storeの所有者は、特定の製品を含む注文に関する統計をチェックする必要があることがあります。

これは、基本的に、OrderLineにProductへの参照を保持する必要があることを意味しますが、は決してとなります。この情報は、データベースに問い合わせる際にのみ、レポート目的で使用します。したがって、このため内部基準の店舗集約内部の何かを「壊す」することはできない。

class OrderLine { 
    // ... 
    public function __construct(Product $product, $quantity) { 
     $this->productName = $product->getName(); 
     $this->basePrice = $product->getPrice(); 
     $this->quantity = $quantity; 

     // store this information, but don't use it in any method 
     $this->product = $product; 
    } 
} 

は、この単純な要件は、製品が集約ルートとなっていることを指示していますか?これは、ProductOptionが集合ルートになるまでカスケードします。これは、Productに参照があるため、ストア外で意味を持たない2つの集計が得られ、リポジトリは必要ありません。私には奇妙に見えます。

コメントは大歓迎です!

答えて

3

にもかかわらずそれは、レポートのみ 'そこにまだビジネス/ドメインの意味があります。私はあなたのデザインが良いと思います。私はOrderLine -> Productの参照を保存して新しい要件を処理しませんでしたが。私はあなたがすでに商品名と価格でやっていることに似た何かをするでしょう。注文ラインに何らかの種類の商品識別子(SKU?)を保存するだけです。この識別子/ SKUは、後で照会で使用することができます。あなたが任意の集計ルールに違反していないと、製品や店舗が安全に、既存またはアーカイブのオーダーに影響を与えずに削除することができます。この方法で

class Sku { 
    private String _storeNumber; 
    private String _someProductIdUniqueWithinStore; 
} 

class OrderLine { 
    private Money _price; 
    private int _quantity; 
    private String _productName; 
    private Sku _productSku; 
} 

:SKUは、店舗と製品自然キーの組み合わせとすることができます。またStoreYからProductXを使用して注文することもできます。

更新:外部キーに関する懸念について。私の意見では、外部キーは、のメカニズムであり、データベースレベルで長寿命のドメイン関係を強制します。ドメイン関係がないので、強制メカニズムも必要ありません。

+0

ありがとう、それは合理的なアプローチと聞こえます。 SKUはありません。自動生成された 'productId'だけです。私がこのアプローチに後悔しているのは、DB内で外部キーを使用する利点を失うことです(私が行った場合、製品を削除すると失敗する)。あなたはこの特定の点について助言をしていますか? – Benjamin

+0

私の最後の編集を参照してください。 – Dmitry

0

この場合、集計ルートとは関係のないレポートの情報が必要です。

サービスに最適な場所(ビジネスに関係する場合はドメインサービス、必要なデータをクエリしてプレゼンテーションやコンシューマ向けにカスタマイズ可能なDTOとして返すクエリサービスなどのアプリケーションサービスより優れている可能性があります)私はあなたの代わりに、クエリモデルとドメインが破損するのDTOを返すだけのリポジトリ(または望ましいファインダを)読んで使用して、必要なデータを照会統計サービスを作成することをおすすめします。

チェックthis

+0

ありがとうございます。これは、商品をOrderLineに明示的に保存することができます: '$ this-> product = $ product;'? – Benjamin

関連する問題