2

私は現在、集計内のエンティティ間の関連付けを処理するという問題に直面しています。

次の例を検討してください。

現在、私たちには ,,User" Entity があり、これは私の集約ルートでもあります。彼は、彼に関連付けられた ,,Product" を 1 つだけ持つことができ、多くの ,,Aliases" を持つことができます。私が現在必要としているのは、関連するものを取得する機能です。 ,,Product" および ,,Aliases" はドメイン モデル内でオンデマンドで作成されます。ユーザーは UserFactory によって作成されます。これは個別に使用することも、データからエンティティを永続的に作成するときに UserRepository 内で使用することもできます。

<?php
class User {
   private $id;

   private $aliases;
   private $product;

   public function isEligibleForCompanyPromotion() {
      //I need a good way to populate this without a performance bottleneck. 
      $product = $this->product;
      [.. code comparing things between User and Product begins ..]
   }     

}

この理由は、ビジネス ロジック (例でわかるように) がオブジェクト間の関連付けに大きく依存しており、オブジェクト間の関連付けに関連するこのロジックはドメイン モデル内で実行する必要があるためです (または、これを移動する必要があるのではないでしょうか? )

次の解決策を検討しました。

1) User が構築されているときに、すべて (関連する Product と Aliases ) をロードするだけです。

長所:

  • 動作しますか?

短所:

  • 大きなパフォーマンスの問題 (残念ながら私はライブの高負荷システムに取り組んでいるので、これを見逃すことはできません)

2) リレーションシップ リポジトリをドメイン モデルに注入する

  private $productRepository;
  private $aliasesRepository;
  [...]

}

長所:

  • 作品..

短所:

  • DDD の目的を打ち負かす ( imo )。ユーザーはリポジトリを内部に持つ必要があります (そのため、ドメイン モデルは永続化に結び付けられます..)

3) 関連付け関連のロジックをドメイン モデルから委任します (おそらくドメイン サービスとポリシーに?)。

長所:

  • また動作します

短所:

  • 実際、これは貧血ドメインモデルにつながるように感じます.ビジネスロジックの大部分はオブジェクトの関係に基づいているため、多くのコードがドメインオブジェクトから移動され、意味がありません.

4) リレーションを処理するための特別な Relationship オブジェクトを作成します。

<?php
class UserFactory { 

private $relationshipFactory;

public function createUser($persistenceData) {
    $user = new User();
    [.. creating of User, populating data etc .. ]
    $user->product = $this->relationshipFactory->createUserProductRelationship($user);
}

}


class UserProductRelationship {

    private $user;
    private $product;
    private $productRepository;

    [.. productRepository is being injected within relationshipFactory, and user is  provided ..]

    public function loadProduct() { 
      [.. load the product based on the relationship criterias ..]
    }

    [.. calls to this object are proxied to lazy-loaded product via __call, __get etc. )
}

長所:

  • また動作します

短所:

  • 循環依存 ( User は UserProductRelationship を内部に持つ必要があり、それに依存しています。 UserProductRelationship は User エンティティと共に提供される必要があります。これら 2 つのクラスを組み合わせると、シナリオ #2 につながります)。

多分私は何かを正しく理解していませんでした..誰かが提案を持っているなら、私はそれについて聞いてうれしいです.

ありがとう!

4

1 に答える 1

1

一部の責任がどのオブジェクトにも属さない場合、またはドメイン オブジェクトが問題を解決するためにあまりにも多くの無関係なデータを必要とする場合は、仕様オブジェクトを導入します。

必要なのは、次のような EligibleForCompanyPromotionSpecification です。

class EligibleForCompanyPromotion {
    private $productRepository;
    private $aliasesRepository;

    public function isSatisfiedBy(User user) {
       //I need a good way to populate this without a performance bottleneck. 
       $product = $productRepository.find(user.productId);
       [.. code comparing things between User and Product begins ..]
}   

class User {
   private $id;

   private $aliasesId;//only identifiers needed
   private $productId;//only identifiers needed 

この場合、ドメイン ロジックはアプリケーション層に漏れず、ユーザーにリポジトリを挿入する必要はありません。

于 2013-12-27T18:23:29.063 に答える