Einzelnen Beitrag anzeigen

MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
555 Beiträge
 
Delphi 10.3 Rio
 
#35

AW: Schon wieder: Warum Interfaces II

  Alt 26. Jun 2020, 19:15
Zumal schon die einsichtigen Beispiele kamen eine kleine Anmerkung.

Eine interface ist bis auf seine syntaktischen Einschränkungen mal die Schnittstelle eines Modul, genauso wie die Klasse eines darstellt und als 'Notlösung' die abstrakten.

Anwendungsgebiert: Datengetriebene Anwendungen in einem nicht trivialen Framework zumeist ekzessiv kombiniert mit Entwurfsmustern.

Konkretes Beispiel: Eine Planungs- und Analyseanwendung für Produktions- und Auftragsdaten in Kombination und das mit praktisch nicht merkbarer Zeitverzögerung von naja pro Planungslauf von 0,5 Sekunden.

Das Framework bestand
a) aus einem (Object)Cache und die darin verwendeten Informationsstrukturen bestimmten das Layout in der DB
a1) darauf basierend Code Generierung, wegen der Migration sowohl der DB als auch GUI Frontendtechnologoie (Winforms vs. WPF usw..)
b) ein GUI Framework bei dem die Kontrollelemente von der Rectangle selbst gemalt wurden
c) tonnenweise PiPaPo im Anwendungsframework
d)

zur Zeit von .net 2.0 bis hinauf 3.5 beginnend WPF.

Das Framework war 'Hollywood' pur. Don't call us, we call you. Der Vorteil war, dass die GUI tatsächlich nur sich um die grafischen Aspekte und die Navigation hat gekümmert, aber die Cacheobjekte gewusst haben was mit ihnen getan werden darf und kann. Beispiel: Die Summen haben sich selbst disaggregiert (in Summanden zerlegt) und die GUI hat nurmehr den passenden Farbton bei der Navigation in die Tiefe in der Summen und der Kopfzeile bereitgestellt.

a1) Damit die Fehlerfreiheit gewährleister bleibt muss man bis zum beim Faktorisieren zum äußersten gehen. Im prozeduralen Paradigma faktorisiert man solange bis die Anzahl der Parameter welche an eine Prozedur (auch welche mit Rückgabetyp welche mit Funktionen an sich mal wenig zu tun hätten) wieder wächst. Im OO Paradigma gibt es dasselbe Spiel bei den Methoden und ... das ganze Spiel erstreckt sich dahinter noch auf die Ebene des Moduls.

Der schlagende Vorteil war, dass die Daten gewusst haben wie sich sich Anzeigen und die GUI auf des Anwendungskontexts auch. Damit reduzierte sich die manuelle Codierarbeit auf ca. 350 Zeilen und der Rest für außenstehende Magic. Das Zeug war monstergeil.

Meine Kollegas haben dermaßen brutal mit Entwurfsmustern über die Stränge geschlagen, dass C# Programmierer welche die Wartung übernehmen wollten (Nachteil von generativen Ansätzen) verzweifelt vor dem Schirm zusammenbrachen.

Die Lernkurve ist gewaltig steil. Du bekommst mit der Zeit, wenn du nicht grausam aufpasst Side Effekts. Ein Freelancer investiert nicht 3 Monate oder mehr, auch wenn diese Schätzung eher der Verzweiflung im ersten Moment geschuldet ist um dann möglw. eine Rechnung schreiben zu können über eine paar Stunden. Die Kompromisslösung war der Sohn eines Geschäftsführers welcher sich neben dem Studium hat eingearbeitet.

Eine groß Berliner Softwarehaus mit mehreren tausend Mitarbeitern kommt auf den Level nicht hin. Diese spezielle Anwendung und die damit verbundenen Anforderungen haben das ganze auch notwendig gemacht, denn die Benutzer der Kunden wollen die eigenen Daten sehen. Also braucht man einen relativ schnittigen Weg die in den Cache zu bekommen. Ein Mittelstandsbetrieb (in .at) macht kein Projekt zu beginn. Allein hat sich schon damals gezeigt (vor ca. 15) Jahre, dass OLAP dafür nicht ausreicht resp. nicht ausgereicht hat.

Das Projekt ist für mich eigentlich die Top Anforderung wo das Ausfahren der Entwurfsmuster am Ende tatsächlich auf fruchtbringend ist. Man hängt halt dann am eigenen Framework fest und dann muss man es anwenden. Unsere Jungs haben das nach dem normalen Arbeitstag von ca. 10 Stunden 6 Tage die Woche selbst entwickelt. Trotzdem gelten die zuvor genannten Restriktionen.

-

Mir fiel allein auf, dass bei viele Projekte dieser exzessive Einsatz heute Standard ist und am Ende alle eher die Nerven raubt. Wenn der SAP Hardcore Profi Programmier kommt und Code mit Field Symbols zur Laufzeit generiert. Das ist schon heftig, aber bei dem integrierten Debugger ließ sich der Ablauf noch verfolgen, dem Code hat man nicht angesehen was er tun soll. Das ganz mit OO-ABAP und alle haben geweint. Endlich hatten alle eine Lösung bei der wenn ein Mitarbeiter umfällt, alle anderen auf einen Knopf können drücken und es geht tatsächlich immer. Blöd nur wenn der Berater umfällt.

Da lobe ich mir die Beispiele hier und auch die im Kommentar zuvor angesprochenen Videos. Interfaces ist eher kleinteilig und sehr verspielt. Bei offensichtlichern größeren Brocken ans Software mit klar abgegerenzten Aufgaben die gemeinhin Komponenten (nicht visuell) heißen, wird die Sache klarer.

-

Das einfachste Interface ist ein (packed) Record der die Daten hält und ein anderer der einen Teilaspekt repräsentiert und alles andere wird ausmaskiert. Damit geht der Typecast nicht schief.

Die Verbundstruktur hält immer nur Daten und Module/Dateien die dazu passenden Funktionen. Die Verbindung macht der Typ und wenn man einen untypisierten Pointer hat, dann kann man jeder Funktion alle Daten übergeben. Die Frage ist wie lange die Sache gutgeht.


Das COM und die Interfaces sind ein Nachbau bei dem anderes wie wie einem PC das OS und der Transaktionsmonitor das Modul salopp formuliert in die Session reingejittet haben. Ein Objekt auf der Instanzebene heute entspricht solch einem geladenen Modul.

Einer der schlagenden Vorteile von Delphi ist einfach, man ein Interface Ebene über das Modul/Unit mehr hat. Ansonsten bist du schnell auf der Schiene einmal Interface - alles Interface. Deswegen hat man dann Interfaces überall. C kennt keine Interfaces sondern Files und Compilation Units und eine Pascal Unit ist auch eine Compilation Unit, aber mit MetaInfo.

Die Initialization Sektion wird beim Start einer Anwendung ausgeführt, als würde ein Modul auf einem Host resp. Co geladen werden. Eine Klasse plus einem Interface ist ein Abstrakter Datentyp. Du kombinierst pro Session eine andere Implementierungen miteinander. Dafür eigenen sich Interfaces sehr gut. Du lädst im Rahmen bspw. der oben genannten Planung eine andere Optimierungsstrategie (könnte man auch in eine DLL packen wie beim SAP APO).

Aus Sicht der Entwicklung. So exzessive Anwendung von Interfaces und Design Patterns macht nur Sinn, wenn der Anbieter am Punkt steht und sagt, 'I was ois, was ich brauche', denn die Anwendung basierte auf Erfahrung von 5 Leuten aus allen Teilen der Datenanalyse in der Praxis und du musst dir am Ende alles selbst schreiben. Sobald du aber spinnende (nicht spinnerte) Analysephasen und Designphasen hast, dann würde ich mal vorsichtig sein mit einer übertrieben Anwendung.

Ich kam nur als Zaungast aus der SAP Beratung vorbei und mein Sitznachbar welcher eher um 18:00 Uhr den Arbeitstag begann haben uns köstlich über die fliegenden Fetzen amüsiert.

Irgendwann mal waren die Jungs fertig und präsentierten Stolz wie Oskar das ganze. Dann habe ich mich hingesetzt und das Konzept im Delphi nachgebaut inkl. dynamischem Laden aus DLLs. Dafür konnte die Implementierung mit D7 andere Aspekte nicht ganz so. Dieses am Ende typenlose und typenbehaftet hinzubekommen bedurfte schon ein massiven Anwendung von Kniffen die nurmehr das .net mit steigender Versionszahl konnte. Mit der Zeit ist der Aspekt auch noch aus der Codegenerierung rausgewandet. Das Zeug ist an sich sehr gut gemacht und die Anwendung sauschnell.

Du hast in so einem Framework bezogen auf die Anzahl der Zeilen aus der DB und deren Inhalt andere Anforderungen. Bei 20k Zeilen aus der Planungsanwendung mit den Aufträgen, hin über die Terminierung und runter auf Produktionsschrittdetail liegen Welten. Die Datenmenge hat gewusst meine Summen bestehen aus Million von Sätzen usw... sobald du der User in Detail geht wurde dahinter der Navigationscontroller ausgetauscht usw... Da diese Anwendung vor der Berechnung der Optimierung selbst die relevaten Spalten hat ermittelt, hat man auch nicht gewusst wieviele vorverdichte Sätze kommen und Drillthrough hat teils transparent in die DB druchgegriffen und nicht mehr auf den Cache.

Nimmt man ein traditionelles Delphi grid, hätte die Zelle eben ein paar Interfaces in dem sie einerseits die Metadaten aus dem Datenbestand holt (eigene Vererbundshierarche) und auf der anderen Seite die 'Engine' welche die Summen aufdröselt.

In dem Punkt sind Interfaces enorm von Vorteil.

Java sorgt mit den Default Implementierungen für mehr Sicherheit im Sinne von Leerobjekten usw... Normalerweise behandelt man solch ein.


  Mit Zitat antworten Zitat