![]() |
Trennung von Darstellung und Daten, Prinzipfrage konkret
Hallo alle miteinander...
Mir geht es um "wie ist es richtig"... 8-) Ich habe: - eine Klasse "Test" - "Test" holt dich aus der Datenbank die Daten und legt die DS in eine Objektlist - die Objektlist wird in eine Listview eingelesen - die Objekte liegen auch komplett in Data der Listview soweit so gut... Nehmen wir an die Daten werden editiert. Wo werden die Daten geändert ? Variante 1: - Änderung des Objektes in Data und bei "Speichern" Data komplett in "Test" zurück. Variante 2: - Änderung der Daten direkt im Objekt in "Test" und die Listview komplett neu einlesen. --> Daten in "Test" sind immer aktuell. Welches ist der sauberste Weg. Ich habe mich für Variante 2 entschieden. Was meint ihr ? Danke für Infos...:hi: Nachtrag: Data ist ein Pointer. Heißt das, daß die Referenz auf die Objektlist in Test zeigt ? Bzw. Data ja keine Kopie des Objektes enthällt. Dann wäre es ja wurscht wo man die Daten ändert... |
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Da Test die Modellklasse ist, ist sie auch für die Daten verantwortlich.
|
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Danke für die schnelle Antwort...
Wenn ich dich richtig verstehe, bin ich mit Variante 2 richtig. :hi: |
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Grundsätzlich hab ich es so gelernt, dass ich für meine Daten eine DatenKlasse schreibe(sofern eine extra struktur von nöten), von der wiederum ich mir die Infos hole, die ich zum anzeigen in meiner visuellen komponennte brauche. Dementsprechen würde ich das editieren der Daten in dem object Test vorziehen und danach dementsprechen die daten in der visuellen komponennte aktualisieren.
Bin aber noch Azubi im ersten Jahr...lass dir das lieber von wem anders bestätigen, vllt werf ich auch was durcheinander :stupid: EDIT: ah MKinzler hats schon beantwortet^^ MFG Memnarch |
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Danke Euch allen... :hi:
|
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Ich nehme an, Du meinst mit Data TListItem.Data. Dadurch, dass Du die Objekte dort ablegst und zusätzlich noch in einer Objektlist hälst Du je Objekt 2 Referenzen. Das kann gefährlich werden, wenn man nicht aufpasst. Sofern die Daten nicht auch noch anderweitig verwendet werden würde ich die Objektliste knicken und die Referenzen komplett in der Listview halten. Du musst dann nur darauf achten, dass Du beim Löschen der Items auch die Objekte wieder freigibst. Und zum Bearbeiten: der einzelne Datensatz (also die Daten des Objektes vom Typ Test) wird geändert, also muss man anschließend ggf. das zugehörige Item Refreshen, aber eben nur dieses und nicht die komplette Listview.
|
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Hallo DeddyH...
ich hätte lieber die Objekte in der Objektlist, da die Klasse auch das Speichern in die DB erledigt. ...also eher auf Data verzichten. |
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Dann hast Du aber das Problem, die Daten dem jeweiligen ListItem irgendwie anders sicher zuordnen zu müssen.
|
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Zitat:
Beide Objektpointer zeigen auf das gleiche Objekt (bzw. Speicherstelle). Also beziehen sich Datenänderungen immer auf beide Objektvariablen. Das Problem ist dann nur, falls Du die Daten z.B. an zwei Stellen darstellt, bei Änderungen auch beide Stellen aktualisiert darzustellen. Das wird üblicherweise über Observer-Pattern gelöst. Ich nutze statt dessen Controller-Komponenten, die von der Datenschicht Änderungsinfos erhalten und ihr angebundenes Control veranlassen, sich ggf. neu darzustellen. Dadurch muss ein Datenobjekt nicht eine Liste von registrierten sichtbaren Contzrols verwalten. |
AW: Trennung von Darstellung und Daten, Prinzipfrage konkret
Ich würde der „Datenklasse“ (unten „Item“) sowie der Klasse „Test“ einfach ein Event OnChanged respektive OnItemChanged (oder so ähnlich) verpassen. „Test“ registriert automatisch für alle seine Items den OnChanged-Handler, und leitet die dort „abgefangenen“ Events dann über OnItemChanged nach außen weiter.
Delphi-Quellcode:
type
TItem = class protected FOnChanged: TNotifyEvent; procedure SetValue(const AValue: integer); public property Value: integer read FValue write SetValue; property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; end; // Typensichere Objektliste, oder unter neueren Versionen TList<Item> TItemList = class(TObjectList) {…} end; TOnItemChanged = procedure (Sender: TObject; Item: TItem) of object; TTest = class protected FList: TItemList; FOnItemChanged: TOnItemChanged; procedure HandleItemChanged(Sender: TObject); public property OnItemChanged: TOnItemChanged read FOnItemChanged write FOnItemChanged; property List: TItemList read FList; procedure LoadData; end; implementation procedure TItem.SetValue(const AValue: integer); begin FValue := AValue; if Assigned(OnChanged) then OnChanged(self); end; procedure TTest.HandleItemChanged(Sender: TObject); begin { …eventuell noch selbst irgendwas tun?… } if Assigned(OnItemChanged) then OnItemChanged(self, Sender as TItem); end; procedure TTest.LoadData; var i: integer; function MakeItem(Value: integer): TItem begin Result := TItem.Create; // wichtig: Result.OnChanged := HandleItemChanged; Result.Value := Value; end; begin for i := 0 to 42 do FList.Add(MakeItem(i)); end;
Delphi-Quellcode:
Das Beispiel habe ich hier nur eben hier im Beitragseditor runtergeschrieben. Es gibt natürlich noch ein paar Dinge, die man in einer echten Anwendung sauberer lösen könnte/müsste (z.B. sollte TItemList irgendein Ereignis bereitstellen, wenn neue Items hinzugefügt werden, damit deren OnChanged-Handler gleich automatisch belegt werden kann), aber es geht hier ja nur um das grobe Prinzip...
type
TMyForm = class(TForm) {…} Listview: TListView; protected FTest: TTest; procedure HandleItemChanged(Sender: TObject; Item: TItem); end; implementation procedure HandleItemChanged(Sender: TObject; Item: TItem); begin { … Listview neuzeichnen (bzw. nur das jeweilige Item) … } end; procedure TMyForm.FormCreate({…}) begin FTest := TTest.Create; FTest.OnItemChanged := HandleItemChanged; end; Wenn das GUI an mehreren Stellen gleichzeitig aktualisiert werden muss, musst du statt Events das Observer-Pattern implementieren (*hust* deshalb wären Multicast-Events toll *hust*). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz