Sebastian Scheid wrote:
[snip]
In dem Teil hatte ich grad ne Menge Kamm-Quoting, kam das von mir (hab
erst seit kurzem Thunderbird als Newsreader)?
[snap]
Um es mal vorwegzunehmen:
Beim Schreiben dieses Posts bin ich zu dem Schluss gekommen, dass deine
Dirty-Flag-Methode tatsächlich die beste ist.
Das ist jetzt die Kurzfassung, wenn du wissen willst, warum, dann kannst
du auch weiterlesen ;)
Post by Sebastian ScheidPost by Michael PetersSagen wir ich definiere, dass alle Zugriffe von außen auf das Model
immer über den Controller laufen müssen, insbesondere die Veränderungen.
Würdest du dann auch die Möglichkeit ausschließen, dass der Controller
Speicherungsanstöße gibt? Wäre ja praktisch, weil ich dann auch nur die
DB-Zugriffe mache, die notwendig sind (der Controller weiß was sich
verändert hat).
Du meinst, in diesem Fall weiß der Controller welche Veränderungen gemacht
wurden, weil nur er sie gemacht hat und niemand anders?
Genau.
Post by Sebastian ScheidDann müsste der
Controller dem Model mit Parametern der save Methode sagen, welche Felder
gespeichert werden sollen?
Das meinte ich etwas anders:
Der Controller verändert im Zuge einer Arbeit ein paar Objekte oder legt
neue an. Diese Objekte bieten alle eine save()-Methode an. Dann könnte
der Controller nach getaner Arbeit diese Objekte abspeichern, und zwar
nur diese und nur in ihrer Gesamtheit (beispielsweise über eine
Transaction), so dass also auch die DB-Konsistenz gewahrt bleibt. Wenn
ich dem gesamten Model sage: "speicher dich mal" und mit den Dirty-Flags
arbeite, würden zwar auch nur die Objekte gespeichert, die sich
verändert haben, aber dafür müsste das gesamte Model durchgeforstet
werden, was bei vielen Objekten evtl. langsamer sein könnte.
Post by Sebastian ScheidDas würde ich eher vermeiden, denn erstens würde ich diese Einschränkung
nicht machen (nur Controller verändert Model). Das Model sollte auch von
außerhalb dieses MVC veränderbar sein. Wenn du immer den Umweg über den
Controller gehst, hast du jede Menge Methoden im Controller, die einfach nur
ans Model forwarden. Ich sehe das als unnötigen Ballast an.
Das stimmt. Allerdings frage ich mich, ob ein Dirty-Flag zu jedem
Attribut (was die Anzahl der nativen Daten-Attribute verdoppelt) nicht
auch solch ein Ballast ist.
Post by Sebastian ScheidZweitens müsste dann der Controller die Aufgabe übernehmen, sich die dirty
Felder zu merken und diese dirty Felder beim speichern auch noch ans Model
übergeben.
Nein er müsste sich nur die _Objekte_ merken, die verändert wurden,
nicht welche Felder (Attribute) in den Objekten. Bzw. muss er sich die
Objekte nichtmal merken, weil er sie ja bei der Benutzung schon hat.
Dann kann er diesen Objekten sagen, dass sie sich speichern sollen.
Dirty-Flags hätte ich in dem Fall nirgendwo. Dabei speichere ich zwar
auch Objekte, die im Zuge der Arbeit zwar benutzt aber nicht verändert
wurden, aber das sollten eher weniger sein, denn irgendwas will man ja
immer verändern.
Post by Sebastian ScheidDie Übergabe ist zu aufwändig (bool Parameter in der save Methode
für jedes Feld oder verschiedene save()-Methoden für jedes Feld... ne warte
da bekommt man es mit Kombinatorik zu tun, gar nicht gut). Außerdem sollen
die Controller ja austauschbar sein. Dann müsstest du dich in jedem
Controller Typ drum kümmern.
Das mit der Kombinatorik fällt dann flach (s.o.). Es stimmt aber, dass
die Controller sich alle darum kümmern müssten. Obwohl es ja nicht viel
Aufwand ist, wenn jeder Controller allen Objekte, die er grad benutzt
hat, noch .save() sagt.
Post by Sebastian ScheidAlso: WIE gespeichert wird (Berücksichtigung von dirty Feldern oder nicht)
gehört ins Model. WANN gespeichert wird haben wir ja oben schon besprochen.
Würde bei mir auch hinhauen:
WAS: Nur die veränderten Objekte.
WIE: Wissen die Objekte in ihrer save()-Methode (also das Model)
WANN: Weiß der Controller, nämlich nach getaner Arbeit. Und zwar ganz
oder gar nicht (Konsistenz).
Post by Sebastian ScheidPost by Michael PetersDamit aber der Controller mit keinen Datenbank-Objekten oder soetwas in
Berührung kommt, könnte ich für jedes Objekt eine save()-Methode
anbieten, die der Controller aufrufen kann um nur das betreffende Objekt
zu speichern.
Für jedes Objekt (du meinst damit doch die Felder deines Models, oder?) eine
save Methode ist das gleiche wie bei jedem setter Aufruf zu speichern. Damit
sparst du keine DB Zugriffe und mit der Integrität der Daten in der DB
bekommst du die o.g. Probleme.
Mit Objekt meinte ich eine Instanz einer Klasse des Models. Also bietet
jede Klasse die save()-Methode zu ihren Objekten. Somit kann ich erst
alle Setter setzen und dann hinterher einmal save() sagen.
Post by Sebastian ScheidPost by Michael PetersDabei werden aber nur die nativen Datentypen
berücksichtigt, die Assoziationen zu anderen Objekten muss der
Controller selbst wieder speichern.
Nein, nein. Siehe oben. WIE gespeichert wird, muss das Model wissen.
Da hast du Recht und damit wären wir bei dem gewichtigen Problem,
welches ich sehe. Bis hier hin ist alles klar, nur nicht wie ich mit den
Assoziationen verfahre. Eigentlich müsste ich auch jeder Ass. sagen,
"speicher dich mal". Aber dann wär ich wieder beim Durchforsten des
gesamten Models unterhalb des Objektes (wenn ich mir alle Instanzen des
Models als Baum vorstelle; wenns ein Busch ist, muss ich sogar das ganze
Model speichern).
Wenn ich das eh nicht vermeiden kann, wäre die Dirty-Flag-Variante
wieder diejenige meiner Wahl.
Post by Sebastian ScheidDas geht halt dann nicht mehr, wenn du verschiedene Views hast und jeder
View einen anderen Controller bekommen soll. Aber wenn du aussschließlich an
der Trennung von Daten/Logik und View interessiert bist (was schon mal sehr
gut ist), dann bauchst du kein extra Controller Objekt.
Ich hab den Controller sogar noch aus einem anderen Grund. Und zwar gibt
es viele Views, die ich sogar selbst noch nichtmal alle kenne. Alle
Views wollen vom Model Informationen bekommen und auch Veränderungen
durchführen. Würde ich die Methoden, die dafür verantwortlich sind,
nicht alle im Controller haben, würden die Views viele Klassen und ihre
Struktur kennen müssen, was es natürlich umständlicher macht. Außerdem
kann ich so sicherstellen, dass keine View etwas macht, was sie nicht darf.
Viele Grüße
Michael