Question

J'ai posé une question similaire un certain temps: Utilisation du modèle Data Mapper, lorsque les entités (objets de domaine) connaissent le mappeur Cependant, il est générique et Je suis vraiment intéressé par la façon d'accomplir quelques choses avec Doctrine2 spécifiquement .

Voici un modèle simple exemple: Chaque Thing peut avoir un Vote d'un User, un User peut recevoir plus d'une Vote mais seulement les derniers comptes de Vote. Parce que d'autres données (Msssage, etc.) est liée à la Vote, lorsque le second Vote est placé le Vote d'origine ne peut pas simplement être mis à jour, il doit être remplacé.

Actuellement Thing a cette fonction:

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

Et Vote prend soin de mettre en place la relation:

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

Il me semble que, pour assurer un User a seulement le dernier Vote compté est quelque chose que le Thing devrait assurer, et pas une couche de service .

Donc, pour maintenir que dans le modèle, la nouvelle fonction Thing:

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

Comment puis-je supprimer le Vote à partir du modèle de domaine? Devrais-je détends Vote::setThing() d'accepter un NULL? Dois-je comprendre une sorte de couche de service qui Thing peut utiliser pour supprimer le vote? Une fois que les votes commencent à accumuler, que foreach va être lente - si une couche de service soit utilisé pour permettre Thing de rechercher un Vote sans avoir à charger toute la collection

Je penche définitivement vers l'utilisation d'une couche de service lumière; cependant, est-il une meilleure façon de gérer ce genre de chose avec Doctrine2, ou suis-je dirige dans la bonne direction?

Était-ce utile?

La solution

Je vote pour la couche de service. J'ai souvent eu du mal à essayer d'ajouter autant de logique sur l'entité elle-même, et moi-même simplement frustré. Sans accès à l'EntityManager, vous êtes tout simplement pas en mesure d'effectuer la requête logique, et vous vous trouverez en utilisant beaucoup d'O (n) opérations ou toute ensembles de relation de chargement paresseux lorsque vous avez seulement besoin de quelques enregistrements (ce qui est super boiteux par rapport à tous les avantages dql offres).

Si vous avez besoin d'aide pour passer au-dessus de l'idée que le modèle de domaine anémiques est toujours un anti-modèle, voir cette présentation par Matthew Weier O'Phinney ou cette question .

Et alors que je pourrais être mal interprété la terminologie, je ne suis pas complètement convaincu que les entités doivent être les seuls objets autorisés dans votre modèle de domaine. Je facilement considérer que la somme des objets d'entité et de leurs services constitue le modèle. Je pense que l'anti-modèle se pose lorsque vous finissez par écrire une couche de service qui paie peu ou pas d'attention à la séparation des préoccupations.

J'ai souvent flirté avec l'idée d'avoir tous les objets de mon entité proxy certaines méthodes de la couche de service:

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

Cependant, étant donné que la doctrine n'a pas système d'événements de rappel type sur l'hydratation de l'objet, je n'ai pas trouvé une façon élégante d'injecter l'objet de service.

Autres conseils

Mon conseil serait de mettre toute la logique de requête dans un EntityRepository puis faire une interface sortir un peu comme:

class BlogPostRepository extends EntityRepository implements IBlogPostRepository {}

cette façon, vous pouvez utiliser l'interface dans vos tests unitaires pour les objets de service et aucune dépendance à l'égard EntityManager est nécessaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top