Dienstag, 4. April 2017

ORM oder doch lieber eine Schichttrennung?

Schichttrennung?

Mit der ersten Windows-Delphi Version fingen alle an "RAD" zu programmieren...

Formular -> Möglichst viele Komponenten visuell oder auch nicht aufs Form klicken und dann immer an den "richtigen" Stellen einen Doppelklick und den Code rein... GGf. noch im OI Verbindungen von Komponente A nach Komponente B herstellen.

<F9> - No errors - ship it...

Plötzlich kommen "die Leute" mit so neumodischem Zeug wie Unittest's oder MVVM...

Also alles wieder aufdröseln und doch trennen...

Nachdem man das alles umgesetzt hat steuern "die Anderen" wieder dagegen und "erfinden" Visual-Live-Bindings also nix im Code, sondern wieder im Formular... OK - muss man ja nicht machen...

Eigentlich ist man mit sich und seinem Source-Code im Reinen.

Da ist die View, eine andere Unit ist das ViewModel, eine dritte Unit hält das DatenModel und die Datenzugriffskomponente, aber ggf. ist das auch eine weitere Unit... Vielleicht hat man für den Datenzugriff auch ein Interface genommen um überhaupt nicht gegen eine physikalische Datenbank zu linken. Good Job! Im Kreis stellen und auf die Schulter klopfen.
 
Jetzt kommt die erste Änderung.
 
Die Änderung passiert als ersten auf der Datenbankebene. Warum? Eine andere Software braucht noch ein Feld... OK... Meine Software muss das ja nicht unterstützen, oder doch? Naja, zu mindestens sollten meine Zugriffe das Feld nicht ändern oder löschen und ggf. bei einem neuen Datensatz initialisieren. Fein - meiner REST-Schnittstelle ist das egal... Darum soll sich der Server kümmern. Aber im Netz muss ich schnell meine Tabellen-Definition anpassen. Fertig... Der Rest meiner Software ist unberührt. Zum Glück muss ich nicht in 30 Formularen etwas anklicken, den die Formulare sind doof und wissen sowie so nix da von. (Gut das man beim erstellen der App's für iOS, Android und Windows daran gedacht hat, und sowie so alles per CRUD/REST/JSON implementiert hat).
 
Anpassung: Eine Unit-Datenbankdefinition und in der INSERT INTO noch das Feld initialisieren. (Wenn überhaupt nötig)
 
Bleiben wir mal bei der Datenbank definition (Um zurück zum Titel zu kommen).
 
Sollte die Datenschicht - also die Unit die einen Datensatz im Speicher hält auch verantwortlich sein für den Zugriff auf die Datenbank?
 
Momentan mache ich es so...:
 
Unit "Person.Model.pas" hat den Person-Record (also eigentlich eine Factory die ein Interface auf eine Class zurück gibt, die die Daten hält.)
Dann gibt es die Datenbank.Define.pas hier stehen die Definitionen aller Datenbanken/Tabellen, die ich in der App verwenden. Will ich die Datenbank ändern gibt es eine Unit und für die eigentlichen Daten, jeweils eine...
 
Jetzt kommen die Leute auf die Bühne die Attribute lieben und sagen: Warum soll ich das trennen, ich kann doch per Attribut in meinem DatenModel direkt angeben wie die Daten gespeichert werden sollen.. Also eigentlich genau wie bei REST/JSON hier kann ich ja z.B. wie in SuperObjects oder bei DUnitX direkt "alles" angeben...
 
Klar, hier gibt es schon fertige Packages die sowas können... Also das RAD neu erfinden?
 
Ich habe zu ORM noch eine geteilte Meinung. Deswegen habe ich auf dem letzten Delphi-Meetup die gleiche Frage gestellt... Und 10 verschiede Meinungen gehört... (Ich möchte sagen alle genannten Argument hatten ihre Berechtigung)
 
Vielleicht bilde ich mir eine Meinung, wenn ich "sowas" selber mal implementiere... Schließlich habe ich ja auch meine eigene JSON, REST Komponente, meinen eigenen XML Reader/Writer meine eigene Tethering Komponente geschrieben.
 
Also - kommt auf die Liste:
 
#Todo, #FDK, #ORM
 
Ich baue mal meinen Fluidcreator für Datenbankdefinitionen um... Mal sehen wie sich das im Source anfühlt...