2012-04-05 10 views
1

Ich habe ein Datenmodell Objekt User. Meine App hat auch einige andere Datenmodellobjekte, zum Beispiel Fork und Options. Benutzer haben Gabeln und Zweige. Meine App muss viele Anfragen mit einer Kombination aus User/Fork/Options etc. Informationen ausführen. Zum Beispiel können Sie eine Seite der Forks des Benutzers sehen. Dies würde eine Abfrage erfordern, die diesen Benutzer (z. B. den angemeldeten Benutzer in der Sitzung) auf Forks verbindet.Gesetz zum Schutz der Demeter mit Modellen

Ich will nicht das Gesetz des Demeter verletzen, und ich bin auch in der Regel gegen Getter (und Setter) im Allgemeinen, so will ich nicht User::getID() oder User::getUsername() implementieren.

Allerdings scheint mir die Alternative nicht viel besser. Was passiert ist, ist, dass ich verschiedene Methoden in User implementieren, um diese Abfragen auszuführen (z. B. User::getForks()). Im Allgemeinen funktioniert das, aber die Klasse User ist monolithisch geworden, was auf seine Art schlecht ist.

Was mehr ist, ich bin mir nicht sicher, wie ich eine Abfrage von zwei Datenmodell-Objekten auflösen würde. Zum Beispiel könnte ich eine User mit einer ID und eine Fork mit einer ID haben und überprüfen möchten, dass die Gabel dem Benutzer gehört. Dies setzt voraus, dass entweder die Fork ihre ID dem Benutzer zugänglich macht, die User ihre ID der Fork zur Verfügung stellt, oder beide ihre IDs dem Controller (oder was auch immer sonst) aussetzt. Keine von diesen scheint wünschenswert, und ich bin nicht sicher, welche zu wählen. Gibt es eine andere Alternative, die ich vermisse?

In einem anderen ähnlichen Schritt bin ich mir nicht sicher, wie Sie der Ansicht am besten Informationen hinzufügen können. Ich habe ein View-Objekt, und in der Regel verwende ich eine Methode wie User::addForksToView(View $view), die eine Abfrage ausführen oder Abfragen und einige Verarbeitung ausführen, aber dies erhöht auch die Größe und die Verantwortung von User. Ich denke, das ist ein ähnliches Problem.

Antwort

1

Anstatt eine getForks Methode im User Objekt, verwenden Sie eine ForksFactory oder etwas ähnliches. Die Fabrik kann Methoden wie fromUser(User $user) und byId($id) haben. Auf diese Weise hat das User Objekt kein hidden dependency auf dem Fork Objekt und wahrscheinlich eine versteckte Abhängigkeit von Datenbankzugriff. Das ForksFactory hat eine Abhängigkeit von der Datenbank und enthält den Code, der nur benötigt wird, um die Daten zu erhalten und Forks zu erstellen, das ist alles, was es zu tun weiß. Wo als Fork Objekt würde keine Abhängigkeit von der Datenbank haben, und jetzt das User Objekt muss nichts über Fork wissen, in der Tat Fork könnte gar nicht existieren und die User ist nicht egal. Dies ist die Idee eines Einzweckobjekts.

Soweit Getter und Setter, warum nicht Eigenschaften wie ID und Name als öffentlich zugänglich machen? Alternativ können Sie die magic methods__get und __set verwenden, um zu steuern, welche Eigenschaften als schreibgeschützt behandelt werden, wenn dies Ihr Anliegen ist. Ansonsten können Sie auch die Eigenschaften freilegen - das ist vollkommen akzeptabel.

Der andere Code, den Sie erwähnen, klingt, als ob er unter dem gleichen Problem leidet - ein Objekt, ein Zweck. Jedes Objekt sollte theoretisch isoliert stehen oder irgendwelche Abhängigkeiten in den Konstruktor injiziert haben. Ihre Objekte sollten nicht erfordern, dass ein anderes Objekt definiert wird oder eine seiner Methoden fehlschlägt.