Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.024 Beiträge
 
Delphi 12 Athens
 
#10

AW: Abgeleitete Klassen auf einzelne Units verteilen

  Alt 28. Jul 2022, 10:59
dass der TParentDevice die einzelnen abgeleiteten TDeviceClasses kennen (und deren Units per zirkulärer Unit-Referenz einbinden) muss ist meiner Meinung nach ein Anti-Pattern und schlechtes Design.
Anti-Pattern würde ich das nicht nennen. Ich hatte ganz bewusst zunächst auf die Auslagerung der Child-Klassen verzichtet und sie erstmal nur im Implementation Teil platziert. Damit sind sie von außen nicht sichtbar. Die Verlagerung in separate Units verläuft dann vollkommen transparent und unsichtbar für den Rest der Anwendung. Auf die Problematik der daraus entstehenden zirkulären Referenzen hatte ich bereits hingewiesen und diese auch bewertet. Hier muss man zwischen Pragma und Dogma abwägen.

Spendiere der Unit mit dem TParentDevice noch eine statische TDeviceController Klasse.
Das würde ich dann sogar gleich in TParentDevice mit class methods realisieren, anstatt den Umweg über eine zusätzliche Klasse zu nehmen.

Allerdings gibt es bei dem Registrierungs-Verfahren noch ein paar Fallstricke.

Zum einen finde ich die Zuordnung über den Typ als string nicht wirklich glücklich. Auf den Enum würde ich nur ungern verzichten, schon wegen der Kompatibilität zum aktuellen Code. Die möglichen Typ-Strings sollten dann ja auch zumindest als Konstanten deklariert werden und dann muss bei einer Erweitung eben doch diese oder eine anderen Unit mit diesen Konstanten angepasst werden. Das ist also kein wirklicher Vorteil von strings und dazu ist der Enum auch noch type-safe.

Zum anderen muss auch behandelt werden, wenn sich zwei Klassen auf denselben Typ oder auf einen Typ keine Klasse registriert. Das ist zwar alles machbar, aber von der Implementierung her doch etwas aufwändiger als eine simple case-Anweisung.

Als drittes muss man noch beachten, dass die Units mit den Child-Klassen ja von keiner anderen direkt verwendet werden und somit entweder explizit in das oder die jeweiligen (auch zukünftige) Projekte aufgenommen werden müssen oder in einer separaten Registrierungs-Unit in der Uses aufzulisten sind, damit sie auch am Ende in der EXE landen.

Und in einem halben Jahr kommt dann eine neue Child-Klasse/Unit dazu und alle Projekte müssen angepasst werden.

In der pragmatischen Variante mit den Mini-Zyklen muss lediglich die Enumeration erweitert werden, die implementation Uses-Anweisung ergänzt und die case-Anweisung erweitert werden. Damit profitieren automatisch alle Projekte die uParentDevice verwenden von der neuen Child-Klasse und die betreffenden Anwender-Units können den neuen Enum-Wert verwenden. Der erweiterte Enum ist übrigens die einzige Änderung, die von außen sichtbar ist - und das ist ja auch so gewollt.

Ich finde das schon eine signifikante Erleichterung zu dem Registrierungs-Ansatz. In anderen Szenarien hat dieser seine Berechtigung, aber hier sehe ich das nicht so.

Es ist sicher hinlänglich bekannt, dass ich ein erklärter Gegner von zirkulären Referenzen bin. Andererseits gilt aber auch: Keine Regel ohne Ausnahme!
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat