Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit (https://www.delphipraxis.net/196894-type-anweisung-im-implementation-abschnitt-vs-registertypes-eigener-unit.html)

bernie110 28. Jun 2018 10:50

Delphi-Version: XE6

Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit
 
Hallo,
lt. diversen Programmiervorschlägen (u.a. von Nick Hodges) soll man ja Interfaces und Implementierungen trennen und möglichst auch in verschiedenen Units speichern. Das sieht dann so bei mir so aus:
Code:
unit uInterface;

interface
type
   IFoo = interface
      ['{BD3EC9DA-3E7A-4839-806E-0DCCA325991C}']
      procedure TuWas;
end;

implementation

end.
und:
Code:
unit uDeklaration;

interface

implementation
uses uInterface;
   type TFoo = class(TInterfacedObject, IFoo)
      procedure Tuwas;
   end;

{ TFoo }

procedure TFoo.Tuwas;
begin
   {... Mach was ...}
end;

end.

Die Registrierung im GlobalContainer hatte ich bisher im Initialization-Abschnitt vorgenommen. Da Stevie aber geschrieben hat (und in den Spring4d-Beispielen auch demonstriert hat):
Zitat:

Beitrag von Stevie in 2014: (https://www.delphipraxis.net/1246971-post14.html)
Noch'n Tip: Lagere das Register in eine extra Unit aus und mach das nicht im initialization Part der Unit mit der Klasse.
Dadurch erreichst du nämlich keineswegs eine Entkopplung sondern nur 1. Untestbarkeit deiner Klasse (dadurch, dass sie im Implementation Teil deiner Unit versteckt ist) und 2. indirekte Kopplung deiner Klasse auf den Container (dadurch, dass die Container Unit im Uses deiner Klassen Unit steht).
habe ich das auch so gemacht:
Code:
unit uRegistration;

interface

uses
   Spring.Container;

procedure RegisterTypes(const aContainer: TContainer);

implementation

uses
   uDeklaration;

procedure RegisterTypes(const aContainer: TContainer);
begin
   aContainer.RegisterType<TFoo>;      // <-- hier tritt ein Fehler auf
   aContainer.Build;
end;

end.
Da die Klasse TFoo nicht sichtbar ist, tritt hier ein Fehler auf!
Wenn ich aber die type-Anweisung in den Interface-Abschnitt verschiebe, gibt es keinen Fehler mehr.

Meine Frage:
Gibt es hier einen Konflikt zwischen 2 verschiedenen Programmierstilen ("Wo soll die type-Anweisung der Klasse stehen" vs. "Auslagerung der RegisterType-Anweisung in eine eigene Unit"), ist meine Annahme, dass die type-Anweisung im Implementation-Teil "versteckt" werden soll, damit die Klasse nicht im Projekt sichtbar ist, übertrieben oder übersehe ich eine Kleinigkeit?

Noch eine Frage am Rande:
Soll in der RegisterType-Anweisung der Zusatz ".Implements<IFoo>" hinzugefügt werden oder nicht?
Wird das Programm dadurch schneller, wenn der Zusatz hinzugefügt ist?

Gruß
Bernie

Uwe Raabe 28. Jun 2018 11:42

AW: Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit
 
Zitat:

Zitat von bernie110 (Beitrag 1406024)
Gibt es hier einen Konflikt zwischen 2 verschiedenen Programmierstielen ("Wo soll die type-Anweisung der Klasse stehen" vs. "Auslagerung der RegisterType-Anweisung in eine eigene Unit"), ist meine Annahme, dass die type-Anweisung im Implementation-Teil "versteckt" werden soll, damit die Klasse nicht im Projekt sichtbar ist, übertrieben oder übersehe ich eine Kleinigkeit?

Durch das Verstecken verhinderst du ja auch, daß die Klasse abgeleitet werden kann. Das ist sicher auch kein guter Stil.

Wer die Klasse braucht, muss eh die Unit usen und dann soll er sie auch sehen. Wer sie nicht braucht, lässt sie einfach weg.

Wie du ja bereits bemerkt hast, funktioniert Stevie's weiser Rat anders auch gar nicht.

Stevie 28. Jun 2018 14:30

AW: Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit
 
Zitat:

Zitat von bernie110 (Beitrag 1406024)
Meine Frage:
Gibt es hier einen Konflikt zwischen 2 verschiedenen Programmierstielen ("Wo soll die type-Anweisung der Klasse stehen" vs. "Auslagerung der RegisterType-Anweisung in eine eigene Unit"), ist meine Annahme, dass die type-Anweisung im Implementation-Teil "versteckt" werden soll, damit die Klasse nicht im Projekt sichtbar ist, übertrieben oder übersehe ich eine Kleinigkeit?

Noch eine Frage am Rande:
Soll in der RegisterType-Anweisung der Zusatz ".Implements<IFoo>" hinzugefügt werden oder nicht?
Wird das Programm dadurch schneller, wenn der Zusatz hinzugefügt ist?

Wie schon an anderer Stelle angemerkt, halte ich das Verstecken einer Klasse im Implementation Teil keineswegs für guten Stil sondern nur für das Ergebnis von "Oh, nein! Ein anderer Entwickler könnte die Klasse direkt nutzen anstatt über das Interface" Paranoia.

Delphi-Quellcode:
.Implements<T>
ist das Explizite registrieren genau dieses Servicetypens T. Implementiert deine an
Delphi-Quellcode:
RegisterType
übergebene Klasse nur ein Interface (IInterface wird ignoriert), dann ergibt sich kein Unterschied. Sind dort aber möglicherweise noch andere Interfaces implementiert, dann registriert der Container diese intern implizit auch, wenn für den Typen nicht schon mindestens eine explizite Servicetyp Registrierung vorliegt.

bernie110 28. Jun 2018 16:37

AW: Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit
 
Danke,
die Antworten haben mir geholfen und vor allem klar gestellt, was in diesem Falle ein guter Programmierstil ist.

Gruß
Bernie

freimatz 29. Jun 2018 11:35

AW: Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit
 
Und das wäre? Typdefinition nun doch in interface-Abschnitt?

Zitat:

Zitat von Stevie (Beitrag 1406042)
Wie schon an anderer Stelle angemerkt, halte ich das Verstecken einer Klasse im Implementation Teil keineswegs für guten Stil sondern nur für das Ergebnis von "Oh, nein! Ein anderer Entwickler könnte die Klasse direkt nutzen anstatt über das Interface" Paranoia.

Das ist leider keine Paranoia sondern Wirklichkeit - zumindest bei uns :wink:

Bei uns wird differenziert. Das folgende gilt nur für Klassen die von "außen" verwendet werden:
  • Definitionen der Klasse im interface-Abschnitt
  • Interface separate unit
  • Solche units in eigene Package

Im Übrigen finde ich es super dass Du dich damit beschäftigst. :thumb:
In der .NET Welt ist das schon länger üblich. Wir haben das schon seit über 6 Jahren. Bei den Delphianer verbreitet sich das nur zögerlich.

Schokohase 29. Jun 2018 11:56

AW: Type-Anweisung im Implementation-Abschnitt vs. RegisterTypes in eigener Unit
 
Wenn eine Klasse nur über das Interface verwendet werden soll, dann erstellt man diese so, dass es nur Sinn macht wenn man das Interface verwendet.
Delphi-Quellcode:
IFoo = interface
  procedure Bar;
end;

TFoo = class( TInterfacedObject, IFoo )
protected
  procedure Bar;
end;
Oder man erstellt eine Klasse, die sich wie eine normale Klassen-Instanz und wie eine Interface-Instanz verhält, was allerdings etwas mehr Tipparbeit bedeutet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz