Was ist der Vorteil von reinen POCO-Modellen?

14

Was ist der Hauptvorteil von reinen POCO-Modellen? Ich verstehe, dass Modelle sauber und einfach sein sollten, aber ich neige dazu, die Pflege von untergeordneten Objekten in den Modellklassen beizubehalten. Zum Beispiel, wenn ich a ClassAund ClassBwie folgt definiert habe:

public class ClassA
{
    public string MyProp { get; set; }
    public IEnumerable<ClassB> Children { get; }

    public void AddChild(ClassB newChild) { /*... */ }
    public void RemoveChild(ClassB child) { /* ... */ }
}

public class ClassB
{
    public string SomeProp { get; set; }
} 

Stimmt etwas mit den Methoden add und remove nicht? Sollte ich stattdessen einfach die Liste verfügbar machen und dem Client-Code erlauben, das hinzuzufügen, was auch immer die Verantwortung für einfache Datenüberprüfungen trägt, z. B. nicht null, und nicht an eine andere Klasse weiterzugeben?

Jede Hilfe wird geschätzt. Danke.

Jesse
quelle
Ich würde die Add / Remove-Methoden entfernen, sofern sie keinen Wert hinzufügen, wie das Übersetzen eines Null-ClassB-Arguments in eine NullObject-Musterversion des Objekts:AddChild(ClassB newChild) => Children.Add(newChild ?? new NullClassB())
Graham
Wenn Sie jemals mit den Kopfschmerzen von ActiveRecord-Klassen mit Hunderten von Methoden umgegangen sind, die möglicherweise zu einem bestimmten Zeitpunkt nicht Ihren Wünschen entsprechen, ist es meiner Meinung nach einfacher, den Reiz zu verstehen.
Casey
Der Hauptgrund, dieses spezielle Design zu vermeiden, liegt darin, dass es den .net-Designrichtlinien widerspricht. Es ist völlig willkürlich, aber die Leute erwarten, dass die Sammlung die Mutationsmethoden enthält.
Frank Hileman
@Casey Ich verwende das Active Record-Muster nicht. Die Add-Methode führt lediglich eine geringfügige Datenüberprüfung durch. Die Methode remove ist vorhanden, da die Auflistung nicht verfügbar gemacht wird. Sie wird einfach einer internen Liste hinzugefügt und daraus entfernt. Ich habe es jedoch geändert, um einen anderen Auflistungstyp zu verwenden, mit dem ich die Validierung durchführen kann, während ich weiterhin die integrierten Methoden zum Hinzufügen / Entfernen verwende.
Jesse

Antworten:

42

Ihre beiden Fragen haben nichts miteinander zu tun.

Was ist der Vorteil von reinen POCO-Modellen?

Ein reines POCO ist nicht abhängig von einem unternehmerischen Rahmen, einer Konvention, [] etwas, oder ist eng mit einem Objekt verbunden, das ähnlich abhängig ist. Mit anderen Worten, die Welt kann sich um einen POCO komplett verändern und es macht einfach weiter, was es macht, ohne sich darum zu kümmern. Sie können es nicht brechen, indem Sie ein Framework aktualisieren, in ein neues System verschieben oder es lustig ansehen. Es funktioniert einfach weiter. Die einzigen Abhängigkeiten sind die Dinge, nach denen explizit gefragt wird.

POCO ist nichts anderes als die POJO-Idee. Das J wurde in ein C geändert, weil die Leute dich komisch ansehen, wenn du ein Konzept erklärst, das Java im Namen hat, wenn diese Leute C # verwenden. Die Idee ist nicht abhängig von der Sprache. Sie hätten es einfach Plain Old Objects nennen können. Aber wer möchte damit prahlen, POO einzusetzen?

Ich werde Fowler die Ursprünge erklären lassen:

Der Begriff wurde geprägt, als Rebecca Parsons, Josh MacKenzie und ich uns auf einer Konferenz im September 2000 auf einen Vortrag vorbereiteten. In dem Vortrag wiesen wir auf die vielen Vorteile hin, die es hat, Geschäftslogik in reguläre Java-Objekte zu codieren, anstatt Entity Beans zu verwenden. Wir haben uns gefragt, warum die Leute so dagegen sind, reguläre Objekte in ihren Systemen zu verwenden, und sind zu dem Schluss gekommen, dass einfache Objekte keinen ausgefallenen Namen haben. Also gaben wir ihnen eines und es ist sehr schön aufgefangen.

martinfowler.com: POJO

Wie für Ihre andere Frage:

Stimmt etwas mit den Methoden add und remove nicht?

Ich mag es nicht, Adirekt darüber Bescheid zu wissen B. Aber das ist eine DIP- Sache, keine POJO- Sache.

kandierte_orange
quelle
Ich hatte der BEinfachheit halber die direkte Abhängigkeit , Idealerweise würden beide Schnittstellen implementieren. Hat aber Anoch eine Liste von IInterfaceB. Stimmt etwas mit der AddChildMethode nicht, wenn die Kinder lose über Schnittstellenreferenzen gekoppelt sind?
Jesse
6
Der Einfachheit halber kann ich eine ganze Menge alberner Dinge tun. Was ich nicht mag, ist, dass A über B Bescheid weiß. A verwendet B nicht, sodass es nicht erforderlich ist, eine eigene A-Schnittstelle zu definieren, über die mit B gesprochen werden kann. Soweit ich das beurteilen kann, ist A eine Sammlung. A sollte sich also mit B durch ein <T> auseinandersetzen, damit es nichts darüber wissen muss.
candied_orange
2
Ich habe auch "PODO" für "einfaches altes Datenobjekt" gesehen, um jegliche Art von Sprachangabe im Akronym zu vermeiden. PODO klingt ein bisschen albern (für mich klingt es wie ein Beiname, das man auf Tatooine hört), mehr als POJO oder POCO, aber deutlich weniger albern als POO.
KRyan
2
Ich frage mich, wie gut Fowlers Präsentation gelaufen wäre, wenn er sie POO genannt hätte.
Oliver
3

Mit Hinzufügen und Entfernen implementieren Sie Collection<T> Funktionen. Fragen Sie sich, warum Sie IEnumerable<T>anstelle von List<T>oder einer anderen veränderlichen Klasse verwenden? Anscheinend liegt es nicht daran, dass Ihre Sammlung nur lesbar sein sollte.

Der einzige Grund, den ich mir vorstellen kann, ist, dass Sie steuern möchten, welche Zugriffsmethoden Sie veröffentlichen möchten. In diesem Fall ist es besser, eine eigene Auflistungsklasse zu erstellen, eine Liste zu kapseln, die ausgewählten Methoden Hinzufügen und Entfernen zu implementieren und zu implementieren IEnumerable<T>. Verwenden Sie dies dann anstelle IEnumerable<T>der Art Ihrer Kindersammlung.

Aber es scheint mir, List<ClassB>würde dir wahrscheinlich nur gut dienen.

Martin Maat
quelle
0

Was wird AddChildhinzugefügt und RemoveChildentfernt? Wenn es aus der Datenbank (oder einem beliebigen Persistenzspeicher) stammt, haben Sie eine Art aktiven Datensatz. Nicht unbedingt immer eine schlechte Sache, aber es bringt Sie definitiv dazu, sich Gedanken über Frameworks, Konventionen, Abhängigkeiten usw. zu machen, wie @CandiedOrange erwähnt.

Was wäre zur gleichen Zeit der Sinn, um eine Abhängigkeit von ClassA zu ClassB (oder zumindest InterfaceB) zu vermeiden, wenn sich alle in derselben Anwendung befinden? In der realen Welt, die Ihre Anwendung modelliert, hängen die Dinge voneinander ab. Objekte der realen Welt verfügen über Sammlungen anderer Objekte, die ihnen "gehören". Es ist völlig angemessen, diese Beziehungen in Ihrem Code darzustellen.

Der einzige Grund, warum es ein wenig komplizierter wird, ist, dass Sie anscheinend genau steuern müssen, wie eine KlasseB mit KlasseA assoziiert wird und von KlasseA getrennt wird. Sie müssen also ein wenig Verhalten implementieren. Sie können es entweder innerhalb der Klasse implementieren (was völlig "legal" ist; siehe /programming//a/725365/44586 ), oder Sie können eine Art separate Klasse haben, die dieses Verhalten enthält. Tun Sie, was für Ihre individuellen Umstände am sinnvollsten ist.

In jedem Fall ist POJO / POCO wirklich nur OOP, wie es gedacht war, schmucklos und unbelastet. Befolgen Sie die OOP-Prinzipien und Sie werden sicher sein.

John M Gant
quelle
Tatsächlich prüft AddChild nur, ob Duplikate vorhanden sind, und lässt auch keine zu. RemoveChild ist vorhanden, da die Auflistung als IEnumerable verfügbar gemacht wird, um das Hinzufügen von Hintertüren zu verhindern. Es wird jedoch nur die Standardentfernung aus der Sammlung ausgeführt.
Jesse
1
Danke fürs Erklären. Ja, das klingt wie genau die Art von Verhalten , das sollte in einem POCO sein und besser auf jedem Fall als nur Ihren zugrunde liegenden IEnumerable für Anrufer Belichtung nach Belieben zu ändern oder zu ersetzen.
John M Gant
Ich denke, Active Record ist nur ein schlechtes Muster.
Casey
1
@Casey, darüber bekommst du keine Auseinandersetzung von mir. Aber ich würde nicht streiten, wenn jemand es auch verwenden wollte. Das Wichtigste war, dass Jesse, wenn er ein Muster wie Active Record verwenden wollte, das die Persistenz mit der Modelldefinition verbindet, alle Probleme hat, die CandiedOrange hervorhebt, und sich nicht wirklich als POCO qualifiziert, für was es sich lohnt. Aber das macht er sowieso nicht.
John M Gant