AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interfaces, Verwenden von Gettern

Ein Thema von Rollo62 · begonnen am 25. Jun 2018 · letzter Beitrag vom 26. Jun 2018
Antwort Antwort
Seite 1 von 2  1 2      
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#1

Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 14:27
Hallo zusammen,

mir fällt beim Testen Folgendes in den FMX Sourcen auf:

Delphi-Quellcode:
  IBrushObject = interface(IFreeNotificationBehavior)
    ['{BB870DB6-0228-4165-9906-CF75BFF8C7CA}']
    function GetBrush: TBrush; // A.) Hier wird ein Getter vorausgesetzt
    property Brush: TBrush read GetBrush;
  end;

  TBrushObject = class(TFmxObject, IBrushObject)
  private
    FBrush: TBrush;
    { IBrushObject }
    function GetBrush: TBrush; // B.) Der Getter wird hier definiert, Result := FBrush;
  protected
    procedure SetName(const NewName: TComponentName); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Brush: TBrush read FBrush write FBrush; // C.) Hier wird direkt auf das Feld zugegriffen
  end;
Ich würde im Design oben IMMER den entsprechenden Getter verwenden, auch bei C.).

Jetzt frage ich mich ob die EMBA C.) Variante evtl. irgendeinen einen Vorteil hat ?
(Ist vielleicht schneller, weil inline und der Getter entfällt).

Ist C.) überhaupt ein sauberes Klassendesign ?
Meiner Meinung nach eher nicht, weil es zwei Arten des Zugriffs gibt.

Rollo
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 14:33
Der Getter bringt hier m.M. nach keinen Vorteil.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 14:36
Ich kann mir nicht vorstellen, dass da ein Konzept oder Plan dahinter steckt.

Ehrlich hätte ich erwartet, dass der Compiler das gar nicht akzeptiert.

Ich halte das für unsauberen Code. Selbst wenn das eine halbe Millisekunde spart wiegt das nicht die Probleme auf, die eine solche Unordnung möglicherweise schafft.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 14:42
Warum sollte der Compiler das nicht akzeptieren? Ist eine "normale" Funktion und eine Property mit Direktzugriff auf die private Variable. Aus dem Namen könnte man die Absicht ableiten, der Compiler aber nicht.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 14:49
Ich kann mir nicht vorstellen, dass da ein Konzept oder Plan dahinter steckt.
Das vermute ich auch.

Ehrlich hätte ich erwartet, dass der Compiler das gar nicht akzeptiert.
Syntaktisch ist das durchaus in Ordnung und kann ja sogar auch beabsichtigt sein, wenn beim Zugriff über das Interface etwas anderes passieren soll, als beim Zugrüff über das Streaming-System.

Ich halte das für unsauberen Code. Selbst wenn das eine halbe Millisekunde spart wiegt das nicht die Probleme auf, die eine solche Unordnung möglicherweise schafft.
Wie gesagt, auch wenn es hier vermutlich nicht so ist, kann so ein Konstrukt auch beabsichtigt sein und im anderen Fall nicht das gewünschte Ergebnis liefern.

Folgendes Szenario wäre hypothetisch denkbar:
Nehmen wir an, das Feld wäre nil, dann würde das so auch in der DFM/FMX gespeichert und auch so wieder gelesen. Der Getter könnte in diesem Fall aber automatisch eine Default-Instanz erzeugen, damit der nil-Fall bei Interface-Zugriff niemals auftritt.

Würde das Property immer den Getter verwenden, würde die Default-Instanz in der DFM/FMX gespeichert und wäre somit nicht mehr default.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.008 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 15:56
Das ist mal wieder der Tatsache geschuldet, dass Properties in Delphi technisch nur halbherzig eine Kapselung darstellen.

Aus OOP und Codesicht habe ich durch eine Eigenschaft in Delphi eine Kapselung hergestellt - also wenn ich auf der konsumierenden Seite auf eine Eigenschaft zugreife, dann kann ich in der implementierenden Klasse, direkt auf die Feldvariable oder über einen Setter wer weiß was machen, ohne dass davon die konsumierende Seite etwas mitbekommen muss oder ich Code anpassen muss.

ABER: Durch die Art der Implementierung (auf der konsumierenden Seite baut der Compiler entsprechenden Code je nachdem ob hinter der Eigenschaft direkt die Feldvariable steht oder ein Getter) ergibt sich die zuvor erwähnte halbherzige Kapselung. Die aus OOP Sicht eine nonbreaking change darstellende Änderung von direktem Feldzugriff auf Setter bedeutet in Delphi tatsächlich technisch (in den Binaries) einen breaking change, da jede Stelle, die in einem solchen Fall lesend auf die Eigenschaft zugreift, neu kompiliert werden muss. Das ist übrigens ebenfalls so, wenn ich den Getter plötzlich als virtual markiere - auch hier erzeugt das einen breaking change für die aufrufende Stelle.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#7

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 20:17
Hallo Stevie,

guter Hinweis, danksehr.

Hallo Uwe,
Zitat:
kann ja sogar auch beabsichtigt sein, wenn beim Zugriff über das Interface etwas anderes passieren soll,
Das fände ich aber sehr bedenklich, und Anti-WYSIWYG

Dann werde ich da wohl nach wie vor bevorzugt dizipliniert über Getter/Setter drauf zugreifen.

Rollo

Geändert von Rollo62 (25. Jun 2018 um 20:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Interfaces, Verwenden von Gettern

  Alt 25. Jun 2018, 21:23
Das fände ich aber sehr bedenklich, und Anti-WYSIWYG
Der Getter ist ja nur die Implementierung des Interfaces und hat ja nicht zwingend etwas mit dem Property zu tun. Betrachte es doch mal wie eine Method Resolution Clause, bei der die Implementierung einer Interface-Methode auf eine andersnamige Methode der Klasse umgeleitet wird, weil es vielleicht schon eine andere Methode mit dem Interface-Namen gibt, die aber ebenso nichts damit zu tun hat.

Du verbindest die Funktion GetBrush ja nur deswegen mit dem Property Brush, weil es die übliche Namensgebung ist. Aus Compilersicht ist GetBrush aber nur die Implementierung des Interfaces.

Sollte der Compiler in diesem Fall etwas verbieten oder erzwingen, fände ich das schon eine gewisse Einschränkung.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#9

AW: Interfaces, Verwenden von Gettern

  Alt 26. Jun 2018, 10:07
Hallo Uwe,

das ist ja richtig, wenn es korrekt implementiert wrd.

Mir geht es aber in erster Linie darum das ich das bekomme was ich erwarte.
Und so eine Getter könnte z.B. auch ungewollte Seiteneffekte haben, also hättee ich mit/ohne Interface unterschiedliches Verhalten bei so einer "simplen" Property.
Naja, schon die TBrush könnte in verschiedenen Ableitungen daherkommen, davon mal abgesehen.

Ich vermeide gerne solche Seiteneffekte und Redundanzen in dem ich möglichst immer die gleichen Routinen verwende, auch wenn es vielleicht manchmal lästig und überflüssig ist.

Das Umbiegen von Methoden kann natürlich auch einen Zweck haben und etwas ganz anderes zurückliefern, aber in der Regel erwarte ich dann bei solchen Klassen dann auch das ich etwas Anderes bekommen kann.

Ich versuche meistend den Code so zu halten das ich auch in 6 Monaten direkt noch weiss was eine Methode bewirkt, ohne erst tiefer reinschauen zu müssen.
Dabei möglichst sprechende Namen verwenden, auch wenn sie recht lang werden können.
Möglichst geradlinig ohne Seiteneffekte und Fettnäpfchen, das meine ich mit WYSIWYG.
Leider gelingt mir das aber nicht immer

Wenn ich aber GetBrush, GetSize, o.ä. sehe, bei relativ simplen Klassen,
dann erwarte ich eigentlich das es keine zwei Wege gibt ohne besonderen Nutzen.

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Interfaces, Verwenden von Gettern

  Alt 26. Jun 2018, 10:14
Ich vermeide gerne solche Seiteneffekte und Redundanzen in dem ich möglichst immer die gleichen Routinen verwende, auch wenn es vielleicht manchmal lästig und überflüssig ist.
Das kann ich durchaus nachvollziehen und prinzipiell unterstütze und empfehle ich dieses Vorgehen natürlich auch.

Was mich in diesem Fall die Augenbrauen hochziehen ließ, war die Bemerkung:
Zitat:
Ehrlich hätte ich erwartet, dass der Compiler das gar nicht akzeptiert.
Da tendiere ich doch eher zu der Haltung "Der Entwickler muss schon wissen, was er tut", bevor ich mir durch den Compiler irgendwelche Zügel anlegen lasse, nur weil der eine oder andere eben manchmal nicht weiß, was er tut.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:04 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