3

しばらく前に同様の質問をしました:データ マッパー パターンを使用して、エンティティ (ドメイン オブジェクト) はマッパーについて知っている必要がありますか? しかし、それは一般的なものであり、具体的に Doctrine2 でいくつかのことを達成する方法に本当に興味があります

以下は単純なモデルの例です: それぞれThingVotefrom aUserを持つことができ、 aUserは複数のキャストを行うことができますが、最後のカウントVoteのみをキャストすることができます。Vote他のデータ (Msssageなど) は に関連しているためVote、2 番目Voteが配置されると、元のデータVoteを更新するだけでなく、置き換える必要があります。

現在Thing、この機能があります:

public function addVote($vote)
{
  $vote->entity = $this;
}

そしてVote、関係の設定を処理します:

public function setThing(Model_Thing $thing)
{
  $this->thing = $thing;
  $thing->votes[] = $this;
} 

aUserが最後にVoteカウントされたものだけであることを保証することは、Thing保証すべきものであり、一部のサービスレイヤーではないように思えます。

したがって、それをモデルに保持するために、新しいThing関数:

public function addVote($vote)
{
  foreach($this->votes as $v){
    if($v->user === $vote->user){
      //remove vote
    }
  }
  $vote->entity = $this;
}

Voteでは、ドメイン モデル内からを削除するにはどうすればよいでしょうか。リラックスVote::setThing()して受け入れる必要がありNULLますか?Thing投票を削除するために使用できるある種のサービスレイヤーを含める必要がありますか? 投票が蓄積し始めると、それforeachは遅くなるでしょう - サービス層を使用して、コレクション全体をロードすることなくThing検索できるようにする必要がありますか?Vote

私は間違いなくライト サービス レイヤーの使用に傾いています。しかし、Doctrine2 でこの種のことを処理するより良い方法はありますか、それとも正しい方向に向かっていますか?

4

2 に答える 2

7

私はサービス層に投票します。私はしばしば、エンティティ自体にできるだけ多くのロジックを追加しようとして苦労し、単にイライラしました。EntityManager にアクセスできないと、単純にクエリ ロジックを実行できず、多数の O(n) 操作を使用したり、少数のレコードしか必要としないときにリレーションシップ セット全体を遅延読み込みしたりすることになります (これは非常に重要です)。 DQL が提供するすべての利点と比較すると不十分です)。

Anemic Domain Model が常にアンチパターンであるという考えを克服するための支援が必要な場合は、Matthew Weier O'Phinney によるこのプレゼンテーションまたはこの質問を参照してください。

用語を誤解している可能性もありますが、ドメイン モデルで許可されるオブジェクトはエンティティだけである必要があるとは完全には確信していません。エンティティ オブジェクトとそのサービスの合計がモデルを構成していると簡単に考えることができます。関心の分離にほとんどまたはまったく注意を払わないサービス層を作成することになると、アンチパターンが生じると思います。

私はよく、すべてのエンティティ オブジェクトでいくつかのメソッドをサービス レイヤーにプロキシするというアイデアを思いつきました。

public function addVote($vote)
{
   $this->_service->addVoteToThing($vote, $thing);
}

しかし、Doctrine にはオブジェクト ハイドレーションに関する種類のコールバック イベント システムがないため、サービス オブジェクトを注入する洗練された方法を見つけられませんでした。

于 2010-12-16T21:38:14.477 に答える
6

私のアドバイスは、すべてのクエリ ロジックを EntityRepository に入れてから、次のようなインターフェイスを作成することです。

class BlogPostRepository extends EntityRepository implements IBlogPostRepository {}

そうすれば、サービス オブジェクトの単体テストでインターフェイスを使用でき、EntityManager への依存は必要ありません。

于 2010-12-19T21:39:27.870 に答える