Doctrine2 Best Practice sollten Entities verwenden Services?
-
11-10-2019 - |
Frage
Ich fragte eine ähnliche Frage eine Weile zurück: Verwenden des Data Mapper Pattern sollte die Entitäten (Domain Objects) wissen um die Mapper? Allerdings war es allgemeine und ich bin wirklich daran interessiert, wie ein paar Dinge zu tun mit Doctrine2 speziell .
Hier ist ein einfaches Beispiel Modell: Jeder Thing
eine Vote
von einem User
haben kann, ein User
kann gegossen mehr als eine Vote
aber nur die letzten Vote
zählt. Da andere Daten (Msssage
, etc) an die Vote
verwandt ist, wenn der zweite Vote
die ursprüngliche Vote
platziert wird, kann nicht nur aktualisiert werden, muss es ersetzt werden.
Zur Zeit Thing
hat diese Funktion:
public function addVote($vote)
{
$vote->entity = $this;
}
Und Vote
kümmert sich um die Beziehung der Einrichtung:
public function setThing(Model_Thing $thing)
{
$this->thing = $thing;
$thing->votes[] = $this;
}
Es scheint mir, dass eine User
Gewährleistung hat nur die letzte Vote
gezählt ist etwas, das Thing
sicherstellen sollte, und nicht einige Service-Layer .
So behalten, dass in dem Modell, die neue Thing
Funktion:
public function addVote($vote)
{
foreach($this->votes as $v){
if($v->user === $vote->user){
//remove vote
}
}
$vote->entity = $this;
}
Wie entferne ich die Vote
aus dem Domain Model? Should I Vote::setThing()
entspannen ein NULL
zu akzeptieren? Soll ich eine Art von Service-Schicht beinhalten, dass Thing
die Abstimmung entfernen können? Sobald die Stimmen akkumulieren beginnen, dass foreach
geht langsam sein - sollte eine Dienstschicht verwendet werden, damit Thing
, ohne die gesamte Sammlung zu laden, die für ein Vote
suchen
Ich bin Neigung auf jeden Fall auf eine Lichtdienstschicht verwendet wird; jedoch gibt es einen besseren Weg, um diese Art der Sache mit Doctrine2 zu handhaben, oder bin ich in der richtigen Richtung?
Lösung
I Abstimmung für die Service-Schicht. Ich habe oft mit dem Versuch, hinzufügen, wie viel Logik auf dem Entity selbst und einfach frustriert mich zu kämpfen. Ohne Zugang zum EntityManager, Sie sind einfach nicht in der Lage Abfragelogik auszuführen, und Sie finden sich finden eine Menge O (n) Operationen oder faul-Laden ganze Beziehung setzt zu verwenden, wenn Sie nur ein paar Datensätze müssen (was ist super lahm, wenn alle im Vergleich die Vorteile dql Angebote).
Wenn Sie etwas Hilfe benötigen über die Idee bekommen, dass die Anemic Domain Model ist immer ein Anti-Muster finden Sie unter diese Präsentation von Matthew Weier O'Phinney oder diese Frage .
Und während ich die Terminologie werden falsch interpretiert konnte, bin ich nicht ganz davon überzeugt, dass Entities sein müssen, die nur in Ihrer Domain Model erlaubt Objekte. Ich würde einfach der Ansicht, dass die Summe von Entity-Objekte und ihre Dienstleistungen bildet das Modell. Ich denke, das anti-Muster entsteht, wenn Sie eine Dienstschicht am Ende zu schreiben, die wenig bis gar keine Aufmerksamkeit auf der Trennung von Bedenken zahlen.
Ich habe oft mit der Idee, alle meine Entitätsobjekten Proxy einige Methoden der Dienstschicht geflirtet:
public function addVote($vote)
{
$this->_service->addVoteToThing($vote, $thing);
}
Da jedoch Lehre hat kein Art Callback-Ereignissystem auf Objekt Hydratisierung habe ich nicht gefunden eine elegante Art und Weise das Dienstobjekt zu injizieren.
Andere Tipps
Mein Rat wäre, alle Abfragelogik in eine EntityRepository zu setzen und dann eine Schnittstelle machen aus ihm ein bisschen wie:
class BlogPostRepository extends EntityRepository implements IBlogPostRepository {}
auf diese Weise die Schnittstelle in Ihren Komponententests für die Dienstobjekte und keine Abhängigkeit von dem EntityManager erforderlich ist, verwenden kann.