Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Projekt auf Interfaces umstellen (https://www.delphipraxis.net/167652-projekt-auf-interfaces-umstellen.html)

TheMiller 11. Apr 2012 15:18

Delphi-Version: 2009

Projekt auf Interfaces umstellen
 
Hallo,

ich habe mich gerade ein wenig mit Interfaces befasst. Ich überlege, ein vorhandenes und recht großes Projekt auf Interfaces umzustellen.

Meine Frage ist jetzt: Ist es möglich - ohne große Risiken und ohne sehr großen Aufwand - ein ganzes Projekt auf Interfaces umzustellen. Und wenn ja, lohnt es sich?

Ich überlege deshalb, weil ich geplant habe, ein Plugin-System für das Projekt zu entwickeln um die exe zu verkleinern. Das sollen DLLs sein und teilweise auch Forms enthalten. Ich weiß noch nicht, ob ich die Plugin-Schnittstelle (das Interface) veröffentlichen möchte. Es sind alles nur Gedanken.

Ich hoffe, ihr könnt mich dahingehend etwas beraten. Mit Plugin-DLLs und darin enthaltenen Forms habe ich Erfahrung. Diese setze ich bereits in zwei Projekten ein, ohne Probleme.

Danke!

stahli 11. Apr 2012 15:41

AW: Projekt auf Interfaces umstellen
 
Mit konkreten Erfahrungen kann ich nicht aufwarten. Aber die beiden Threads könnten interessant für Dich sein:
http://www.delphipraxis.net/166192-s...r-dummies.html
http://www.delphipraxis.net/166899-i...eferenzen.html

Ich sehe 2 Vorteile bei der Verwendung von Interfaces (in Delphi)
- die Speicherverwaltung ist automatisiert
- die Units Klassen sind deutlich besser voneinander entkoppelt

Als Nachteil ist sicher die erhöhte Schreibarbeit und ein gewisser Lernbedarf am Anfang zu nennen.

Ein "normals Projekt" auf Interfaces umzustellen, dürfte sich lohnen, wenn man sehr komplexe Beziehungen zwischen den Klassen herstellen muss und Probleme mit der Speicherverwaltung der Objekte hat. Mit Interfaces lässt sich das m.E. abstrakter und übersichtlicher handeln.

Wenn Du Objekte an eine DLL übergeben willst, geht das m.E. nur über Interfaces - stimmt das? Ich habe damit noch nie gearbeitet.

s.h.a.r.k 11. Apr 2012 16:16

AW: Projekt auf Interfaces umstellen
 
Solltest dir dies bzgl. auch mal die Serie von Nick Hodges anschauen. Ich finde, es lohnt sich wirklich. habe im Moment Spring im Einsatz und bin davon sehr überzeugt und freue mich jeden Tag aufs neue, wo schön Dinge doch sein können. Aber es Bedarf halt etwas an Verständnis für die Materie.

Aufwand und Risiken wirst du aber immer haben, da du ja ein sinnvolles Konzept erstellen solltest. Blind von jeder Klasse ein Interface definieren und loslegen hat imho nur den Vorteil der automatischen Speicherverwaltung. Hat man aber FastMM im Einsatz, so kann man das Problem der Speicherleichen aber schon von vorn herein bekämpfen. Beim Umstieg solltest du ruhig einen Schritt weiter gehen, imho.

@stahli: man entkoppelt nicht Units voneinander, sondern man schafft eine lose Kopplung. Klassen hängen nicht mehr direkt voneinandere ab, sondern eben nur noch von den definierten Schnittstellen, egal welche Klassen diese implementieren.

mkinzler 11. Apr 2012 16:35

AW: Projekt auf Interfaces umstellen
 
Die Frage ob ein vorhandenes Projket einfach und problemlos auf Interfaces umstellbar ist, ist nicht so einfach. Im Zweifel würde ich diese deshalb mit Nein beantworten

Stevie 11. Apr 2012 16:38

AW: Projekt auf Interfaces umstellen
 
Klares "kommt drauf an". Hängt vom vorhandenen Design der Anwendung ab. Lässt sich diese ohne große Umbauten auf Interfaces umstellen, ohne dass du in AVs und invalid pointer Exceptions rennst, weil das ganze Lifetime Management deiner Instanzen so vertrackt ist.

Bei der Benutzung von Interfaces musst du dir auch im Klaren darüber sein, wie das Interface aussehen soll und ob du bei einem Plugin System abwärtskompatibel sein möchtest so dass nicht alle Plugins bei einer Erweiterung/Änderung des Interfaces neu erstellt werden müssen. Wie sehen die Signaturen deiner Interface Methoden aus. Benutzt du dort eigene Typen, sollten diese eventuell in ein Package.

Auch die VCL und jegliche TComponents vertragen sich nicht immer mit Interfaces, da ihr Lifecycle nicht über die Interface Referenzzählung gesteuert wird, sondern über den Owner. Das kann schnell zu AVs führen (TComponent wird über den Owner Mechanismus freigegeben, aber eine Interface Referenz auf diese Komponente ist noch irgendwo vorhanden).

Dass die Interface Referenzzählung nicht mehr greift, wenn man sich überkreuzende Referenzen hat (Parent/Child Relation z.B.), sollte man auch beachten.

Ich selber mag Interfaces sehr gerne, da sie einem ein gutes Stück eine Art GC vorgaukeln, aber man sollte über die Gefahren im Klaren sein und darüber dass in der Theorie immer alles ganz einfach gesagt ist "always code against interfaces" aber in der Praxis nicht immer realisierbar.

himitsu 11. Apr 2012 16:48

AW: Projekt auf Interfaces umstellen
 
Forms in DLLs auslagern ... da muß man aber auch etwas aufpassen.

TheMiller 11. Apr 2012 17:10

AW: Projekt auf Interfaces umstellen
 
Hallo.

Vielen Dank für die zahlreichen Antworten. Nach alldem habe ich mich entschlossen, das mit den Interfaces etwas aufzuschieben und das Projekt erstmal so zu warten. Dann, wenn ich mehr Zeit habe, werde ich mit Interfaces neu (parallel) entwickeln und dann die "alte Version" aufgeben.

Aber ich werde mich damit dann doch noch beschäftigen, nur halt später.

Vielen Dank

himitsu 11. Apr 2012 17:23

AW: Projekt auf Interfaces umstellen
 
Wenn es dir nur um die Größe geht, dann kannst du es notfalls auch mit Laufzeitpackages versuchen.

TheMiller 11. Apr 2012 17:48

AW: Projekt auf Interfaces umstellen
 
Danke für den Tipp. Es geht mir nicht nur um die Größe, aber sie spielt auch eine Rolle ;)

Das Programm nutzen recht viele Leute, da werde ich lieber erstmal genau überlegen, was ich will und mich nochmal genau über Interfaces informieren. Ich weis ja momentan noch nichtmal, ob ich wirklich ein Plugin-System entwickeln will.

Ich denke lieber nochmal nach. Wenn ich in ein paar Wochen wieder mehr Zeit habe, dann weis ich bis dahin bescheid, was ich will und werde dann ggf. parallel entwickeln.

Danke

himitsu 11. Apr 2012 18:37

AW: Projekt auf Interfaces umstellen
 
Wobei die Interfaces nicht die einzigen Dinge sind, worüber du nachdenken mußt.

Auch alles, was über dieses Interfaces hin- und hergereicht wird, muß berücksichtigt werden.

VCL-Komponenten über DLL-Grenzen hinweg zu behandeln könnte Probleme bereiten,
auch auf andere Objekte oder Strings muß man aufpassen,
vorallem da standardmäßig der Speichermanager und die RTTI nicht gemeinsam verwaltet werden.

Ausschließlich der WideString kann problemlos übergeben werden, da dieser nicht vom Delphi verwaltet wird, sondern global über die WinAPI (MSDN-Library durchsuchenSysAllocString und Co.).
Er steht damit sogar in C und anderen Sprachen zur Verfügung.
Auch Records und statische Arrays, aus einfachen Typen, sind problemlos möglich.

neo4a 11. Apr 2012 18:45

AW: Projekt auf Interfaces umstellen
 
Zitat:

Zitat von Stevie (Beitrag 1161289)
Auch die VCL und jegliche TComponents vertragen sich nicht immer mit Interfaces, da ihr Lifecycle nicht über die Interface Referenzzählung gesteuert wird, sondern über den Owner.

Das lässt sich relativ elegant umgehen, indem man genau 2 Dinge tut:
- Das fragliche TComponent wird von einem TInterfacedObject verwaltet.
- Unser TComponent bekommt als Owner NIL oder einen "Langläufer" z.B. TAplication.Mainform

Delphi-Quellcode:
type

IMyVCLComponent = interface
  procedure SetParent(aParent : TWinControl);
end;

TMyVCLComponentObject = class(TInterfacedObject, IMyVCLComponent )
private
  FMyVCLComponent : TComponent;
private // IMyVCLComponent
   procedure SetParent(aParent : TWinControl);
public
  constructor Create;
  destructor Destroy; override;
end;

implementation;

constructor TMyVCLComponentObject.Create;
begin
  FMyVCLComponent := TComponent.Create(nil);
end;
 
destructor TMyVCLComponentObject.Destroy;
begin
  FMyVCLComponent.Free;
  inherited;
end;

procedure TMyVCLComponentObject.SetParent(aParent : TWinControl);
begin
  FMyVCLComponent.Parent := aParent;
end;
Mit dieser Konstruktion lassen sich (VCL)-Komponenten auch leicht mittels Spring4D verwalten. Ein weiterer erwünschter Effekt ist die damit mögliche vollständige Entkopplung von Dritt-Units und/oder -Libs vom Hauptprogramm. Kein Licht ohne Schatten: Durch die erforderliche dynamische Erzeugung zur Laufzeit muss man auf den Delphi-Designer verzichten.

Zitat:

Zitat von Stevie (Beitrag 1161289)
"always code against interfaces"

Aber allein durch den Versuch, sehen die Programme gleich ganz anders aus ;)

Stevie 12. Apr 2012 07:32

AW: Projekt auf Interfaces umstellen
 
Es ging um die Umstellung eines vorhandenen Programms auf Interfaces und nicht um den Start auf der "grünen Wiese" - und da lässt sich nicht alles mal so umsetzen.

neo4a 12. Apr 2012 19:12

AW: Projekt auf Interfaces umstellen
 
Zitat:

Zitat von Stevie (Beitrag 1161407)
Es ging um die Umstellung eines vorhandenen Programms auf Interfaces und nicht um den Start auf der "grünen Wiese" - und da lässt sich nicht alles mal so umsetzen.

Schon klar. Nur habe ich den beschriebenen Ansatz auch bereits recht erfolgreich bei Alt-Projekten einsetzen können. Dabei ging es insbesondere um die Entflechtung von zusammengeklickten Komponenten verschiedener Libs.

Ein angestrebtes Maß dabei war z.B., dass keine Unit mehr als 1000LOC umfasst.

Für mich persönlich war diese Herangehensweise (also ausgehend von einem Bestands-Projekt) auch deshalb sehr positiv, weil ich mich nicht so sehr auf Programm-Features und UI-Design konzentrieren musste, sondern ganz gezielt mittels CleanCode-Prinzipien und Design-Pattern den ziemlich typischen Delphi-Klick-Code zerlegt habe. Als ich den Bogen raus hatte, machte es nicht nur Spaß, sondern ging auch ziemlich flott.

Im Gegensatz zu der hier schon häufig gelesenen Ankündigung, es beim nächsten Projekt "richtig" anzugehen, glaube ich da nicht so dran: Neue Projekte gleichzeitig mit neuen Ansätzen ohne belastbare Erfahrung anzusetzen, ist m.E. fahrlässig und dürfte meistens in der einen oder anderen Form scheitern.

Stevie 13. Apr 2012 07:47

AW: Projekt auf Interfaces umstellen
 
Ehrlich gesagt, würde mir der Ansatz nicht gefallen, weil ich es ehrlich gesagt hasse, wenn man seine UI zur Laufzeit erzeugt und man keine Möglichkeit hat, sich mal ebend im Designer anzuschauen, wie das Form aussieht und/oder mal ebend was verschiebt etc.

Ich kenn das aus unserem Produkt, dort gähnt einen im Designer ein leeres graues Form an, welches zur Laufzeit zig verschiedene Komponenten enthält.

Genau aus diesem Grunde habe ich ja beim DSharp MVVM Ansatz versucht, beide Konzepte unter einen Hut zu bringen. UI zusammen klicken, aber keine Events oder sonstiges implementieren, sondern im ViewModel machen, welche dann gebunden werden.

sx2008 13. Apr 2012 07:50

AW: Projekt auf Interfaces umstellen
 
Wenn man Interfaces einsetzt muss man gleichzeitig auch einen Preis dafür bezahlen.
Man muss die Methoden nicht nur im Interface deklarieren, sondern auch in den Klassen nochmals mit genau gleicher Signatur deklarieren.

Das mag auf den 1. Blick noch kein Problem darstellen; man muss ja nur die Methoden aus dem Interface kopieren und in die betroffenen Klassen einfügen (per Copy & Paste).
Es baut sich aber ein gewissen psychologischer Widerstand gegen das Ändern von Interfaces auf.
"Eigentlich müsste ich ja noch eine weitere Funktion in das Interface XY einbauen, aber dann muss ich das in 5 weiteren Klassen nachziehen. Da hab' ich gerade keine Zeit dafür, drum lass ich es lieber mal so wie es ist"

Daraus kann man den Schluss ziehen, dass wenn man Interfaces verwendet, sollte man dies sehr sorgfältig tun. :warn:
Wenn man z.B. Methoden in ein Interface aufnimmt, die später eigentlich gar nicht gebraucht werden, dann ist das auch verschwendete Arbeit und ein Störfaktor im Sourcecode.

Als Delphi-Programmierer muss man aber noch einen weiteren Preis bezahlen; das leidige Thema mit der Referenzzählung von Interfaces.
Sobald man ein Objekt über ein Interface anspricht, hat man die Verantwortung für die Lebensdauer praktisch an die Referenzzählung abgetreten.
Danach darf oder sollte man das Objekt nicht mehr über die normale Objektvariable ansprechen.
Es gibt da Dinge die das Programmieren im gemischten Umfeld von Interface-Zeigern und Objekt-Zeigern nicht gerade einfach machen.
Ein .NET-Programmierer hat es da viel einfacher (*), da Objekt- und Interface-Referenzen unter .NET einer gemeinsamen Garbagecollection unterliegen.

Fazit:
Interfaces sind eine gute Sache, wenn man sich der Vor- und Nachteile genau bewusst ist.
Ein Projekt "auf Interfaces unzustellen" macht keinen Sinn;
wenn man aber gezielt neue Interfaces einführt (z.B. für Plugins) und weiss was man tut
ist man auf dem richtigen Weg.

*) neidisch kuck

himitsu 13. Apr 2012 08:58

AW: Projekt auf Interfaces umstellen
 
Zitat:

Zitat von sx2008 (Beitrag 1161653)
Es baut sich aber ein gewissen psychologischer Widerstand gegen das Ändern von Interfaces auf.

Interfaces ändert man nicht, vorallem nicht, wenn sie über Modulgrenzen hinweg und/oder gar von anderen Personen/Programmen (z.B. Plugins) verwendet werden.

Man könnte sie manchmal noch erweitern, aber besser währe dann eine Vererbung und das Neue Interface unter anderem Namen zu veröffentlichen.

Ganz schlimm wäre es, wenn sich parameter ändern, dann kommt es garantiert zu Problemen, also wenn man bestehende Funktionen ändert.
(Neues hinten dran = weniger/kein Problem)

stahli 13. Apr 2012 10:55

AW: Projekt auf Interfaces umstellen
 
Zitat:

Zitat von sx2008 (Beitrag 1161653)
Das mag auf den 1. Blick noch kein Problem darstellen; man muss ja nur die Methoden aus dem Interface kopieren und in die betroffenen Klassen einfügen (per Copy & Paste).
Es baut sich aber ein gewissen psychologischer Widerstand gegen das Ändern von Interfaces auf.
"Eigentlich müsste ich ja noch eine weitere Funktion in das Interface XY einbauen, aber dann muss ich das in 5 weiteren Klassen nachziehen. Da hab' ich gerade keine Zeit dafür, drum lass ich es lieber mal so wie es ist"

Mir wird immer bewusster, dass, wenn man sich Arbeit sparen will und man etwas "mal eben auf dem kurzen Wege" löst, man dies später irgendwann mit deutlich mehr Aufwand wieder korrigieren muss.
Also mehr Tippaufwand würde ich für eine übersichtlichere Projektstruktur inzwischen immer in Kauf nehmen (jedenfalls für ein ernsthaftes Projekt).
Deshalb erscheinen mir Interfaces inzwischen auch reizvoll.


Zitat:

Zitat von neo4a (Beitrag 1161630)
Im Gegensatz zu der hier schon häufig gelesenen Ankündigung, es beim nächsten Projekt "richtig" anzugehen, glaube ich da nicht so dran: Neue Projekte gleichzeitig mit neuen Ansätzen ohne belastbare Erfahrung anzusetzen, ist m.E. fahrlässig und dürfte meistens in der einen oder anderen Form scheitern.

Falls ich (u.a.) gemeint bin: Natürlich werde ich einige Tests durchführen und mich an das Thema heran tasten. Da ich jetzt schon eine ganz gute Projektstruktur habe, halte ich einen Neuaufbau mit Interfaces für durchaus machbar. Die Daten und die GUI blieben gleich. Das Framework darum müsste erneuert werden. Jedenfalls freue ich mich schon drauf und inzwischen habe ich ja auch schon diverse Ansätze durch und ein paar Erfahrungen gemacht. :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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-2025 by Thomas Breitkreuz