Domanda

Ho fatto una domanda simile un po 'indietro: Uso della pattern Data Mapper, se gli enti (Domain Objects) conoscono il Mapper? Tuttavia, era generico e sono davvero interessato a come realizzare un paio di cose con Doctrine2 specificamente .

Ecco un modello semplice esempio: Ogni Thing può avere un Vote da un User, un User può esprimere più di un Vote ma solo gli ultimi conteggi Vote. Perché altri dati (Msssage, ecc) è legato alla Vote, quando la seconda Vote è collocato il Vote originale non può semplicemente essere aggiornato, ha bisogno di essere sostituito.

Al momento Thing ha questa funzione:

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

E Vote si prende cura di impostare il rapporto:

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

Mi sembra che garantire un User ha solo l'ultimo Vote contato è qualcosa che l'Thing dovrebbe garantire, e non un livello di servizio .

Quindi, per mantenere che nel modello, la nuova funzione Thing:

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

Allora, come faccio a rimuovere il Vote dall'interno del modello di dominio? dovrebbe mi rilasso Vote::setThing() ad accettare un NULL? Dovrei comportare un qualche tipo di livello di servizio che Thing può utilizzare per rimuovere il voto? Una volta che i voti iniziare ad accumulare, che foreach sta per essere lento -? Se un livello di servizio essere utilizzata per consentire Thing per cercare un Vote senza dover caricare l'intera collezione

Sono decisamente sporgendosi verso utilizzando un livello di servizio di luce; tuttavia, c'è un modo migliore per gestire questo tipo di cose con Doctrine2, o sto andando nella direzione giusta?

È stato utile?

Soluzione

Io voto per il livello di servizio. Ho spesso lottato con il tentativo di aggiungere il più logica per l'entità in sé, e semplicemente me stesso frustrato. Senza l'accesso al EntityManager, si è semplicemente non in grado di eseguire query di logica, e vi ritroverete con un sacco di operazioni O (n) o pigro-caricamento set di tutto il rapporto quando hai solo bisogno di un paio di record (che è super zoppo rispetto a tutti i vantaggi DQL offerte).

Se avete bisogno di qualche aiuto superando l'idea che il modello di dominio anemico è sempre un anti-modello, vedi questa presentazione da Matthew Weier O'Phinney o questa domanda .

E mentre potrei interpretando male la terminologia, sto non del tutto convinto che le entità devono essere gli unici oggetti permesso nel vostro Domain Model. Vorrei facilmente considerare che la somma di entità oggetti e la loro servizi costituisce il modello. Credo che l'anti-modello si pone quando si finisce per scrivere un livello di servizio che presta poca o nessuna attenzione alla separazione degli interessi.

Mi sono spesso flirtato con l'idea di avere tutti gli oggetti delega alcuni metodi per il livello di servizio la mia entità:

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

Tuttavia, poiché Doctrine non ha alcun sistema di evento di callback tipo su un oggetto idratazione, non ho trovato un modo elegante per iniettare l'oggetto del servizio.

Altri suggerimenti

Il mio consiglio sarebbe quello di mettere tutta la logica di query in un EntityRepository e poi fare un'interfaccia fuori di esso un po 'come:

class BlogPostRepository extends EntityRepository implements IBlogPostRepository {}

In questo modo è possibile utilizzare l'interfaccia nella vostra unità di test per gli oggetti del servizio e nessuna dipendenza dalla EntityManager è richiesto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top