![]() |
Frage zu Propertys
Hallo,
wenn ich eine Klasse schreibe und eine Property lesen und schreiben möchte, dann schreibe ich mir für das Schreiben immer einen "Setter", wie es ![]() Aber was spricht denn gegen
Delphi-Quellcode:
?
property Name: String read FName write FName;
Ich schreibe ja auch nicht für jede Property einen "Getter"... Gruß, Lukas |
AW: Frage zu Propertys
Eigentlich gar nichts.
|
AW: Frage zu Propertys
Hmmm... Dann werde ich das in Zukunft so machen :thumb:
|
AW: Frage zu Propertys
ist mehr zu schreiben als
Delphi-Quellcode:
und anschließend Shift+SRTG+C
property Name: String;
|
AW: Frage zu Propertys
Und mehr überflüssiger Code.
|
AW: Frage zu Propertys
Zitat:
Delphi-Quellcode:
und TAB und den Namen :mrgreen:
propf
|
AW: Frage zu Propertys
Wo war jetzt nochmal im Eingangspost die Bemerkung, das die Anzahl der Tastendrücke irgendeine Rolle spielt? :gruebel:
|
AW: Frage zu Propertys
Wenn im Setter absolut nichts gemacht wird, außer in das Feld zu schreiben, dann ist der natürlich sinnlos und du kannst direkt in das Feld schreiben.
Vom Code her ist es dennoch möglich später einen Setter einzufügen, wenn dieser nun doch benötigt wird. Der Vorteil beim Setter ist, daß du dort einen Haltepunkt reinmachen kannst, um Schreibzugriffe zu debuggen. Oder man kann dort den zugewiesenen Wert prüfen und ungültige Werte unterbinden. Aber, wie bereits erwähnt, dannst du den nötigen Setter dann immernoch einbauen. Zitat:
![]() ![]() ... PS: Diese Vorlagen erzeugen sogar das Feld
Delphi-Quellcode:
, wenn es noch nicht existiert.
FName: string;
[add] ![]() Das Tutorial sollte man besser mal reparieren. :wall: Zitat:
Und wo ist das Override? Und wo sind die Inherited? Und weiter wollte ich nicht mehr schauen, da ich Angst bekommen hab. |
AW: Frage zu Propertys
Wenn ich noch etwas hinzufügen darf:
Properties mit direkten Lese- und/oder Schreibzugriff auf Variablen sind meines Erachtens unsauber und "starr" (natürlich gibt es wirklich Ausnahmen, bei denen es sich für uns Delphi-Entwickler vielleicht wirklich nicht lohnt extra Getter/Setter anzulegen). Aber letztendlich entspricht das der Veröffentlichung einer Variable (also "public FVariable: Integer" (Lesen + Schreiben)) und ist auch in anderen Sprachen eher ein NoGo würde ich sagen. Es macht meines Erachtens in den meisten Fällen durchaus Sinn sich die "Mühe" zu machen Getter und Setter zu schreiben, da man so viel flexibler ist. Außerhalb deiner Klasse hat es niemanden zu interessieren was Du intern machst (z.B. den Wert in die entsprechende Variable zu schreiben). Mit Flexibel meine ich: Du musst deine Property-Deklaration nicht anpassen wenn Du die interne Variable änderst (read/write Sektion) und Du kannst problemlos weitere Aktionen innerhalb der Getter und Setter antriggern, die im Laufe der Entwicklung vielleicht noch kommen (nach dem Setzen z.B. Log schreiben, vor dem Lesen ein Flag setzen oder sonst was). Ich finde es am elegantesten gleich mit Interfaces zu arbeiten, wo Du dann auch gezwungen wärst (;-))Getter und Setter zu implementieren. Hier hast Du dann in den Tests auch den Vorteil, deine Klassen einfacher zu mocken (durch Testklassen auszutauschen). |
AW: Frage zu Propertys
Zitat:
Zitat:
Zitat:
|
AW: Frage zu Propertys
Welchen Unterschied macht es für den Benutzer einer Klasse, ob eine Property so deklariert ist
Delphi-Quellcode:
oder so
property SomeProp: integer read FSomeProp write FSomeProp;
Delphi-Quellcode:
?
property SomeProp: integer read GetSomeProp write SetSomeProp;
|
AW: Frage zu Propertys
Zitat:
|
AW: Frage zu Propertys
Zitat:
Zitat:
|
AW: Frage zu Propertys
Zitat:
-Der Konsument der Klasse sieht nicht, ob es sich um einen direkten Zugriff auf die Variable handelt oder ein Getter/Setter involviert ist. -Der Typ der Internen Varibel kann unabhängig vom Typ der Property geändert werden ( u.U. muss man dann Getter/Setter implemnetieren) -Man kann nachträglich Getter/Setter einführen ohne das der Konsument etwas davon merkt- Zitat:
Zwingend Setter/getter zu verwenden und nur bei Java so, weil es dort keine Properties gibt! In C# wurde im Großen-und-Ganzen das Verhalten von Delphi übernommen ( sogar vereinfacht, da inline) |
AW: Frage zu Propertys
Zitat:
Nach der Argumentation könnte man doch theoretisch auch fragen wofür man überhaupt Klassen und Klassenmethoden verwendet, anstatt diese "einfach" prozedural ohne Klasse runterzutippen und globale Variablen zu verwenden. Das geht mit Sicherheit auch schneller (geringerer Aufwand) und ist vielleicht beim Zugriff auch schneller ohne die Klassenzuordnung ;-) (wobei ich mir bei den Methodenaufrufen performancetechnisch keine Gedanken mache, außer vielleicht ich entwickle für eine wirklich schwache Platform (TV embedded oder ähnliches)). Und was C# angeht: Soweit ich mich erinnere kann ich da auch nicht direkt auf eine Variable verweisen, sondern habe lediglich die Möglichkeit, Getter und Setter in "verkürzter" Form zu implementieren - muss aber trotzdem einen Wert rausgeben (Result := FBla) und einen Wert verarbeiten (FBla := AValue), was dann wiederum einer Kapselung in eine Methode entspricht. |
AW: Frage zu Propertys
Zitat:
In C# sieht das so aus:
Code:
private int var; // Variablendefinition
public int Var // Property-Definition { get{ return var; } // Getter set{ var = value; } // Setter } |
AW: Frage zu Propertys
Zitat:
Zitat:
Zitat:
Zitat:
Code:
Nennt sich Autoproperty und ist einfach die Konsequenz aus dem, was Du ablehnst.
public int Var {get;set;}
|
AW: Frage zu Propertys
Zitat:
Zitat:
Zitat:
Wenn ich eine Property
Delphi-Quellcode:
verwende, dann verwende ich kein Interface für den Zugriff darauf. Wenn ich kein Interface verwende, habe ich keinen definierten Zugriff auf eine Klasse und kann diese in Delphi entsprechend nicht so einfach für den Test mocken. (außer ich mache es Quick and Dirty und erstelle mir im Testprojekt eine Kopie der Unit und implementiere dort meinen Stubcode). Und das ist eben der Grund warum ich den "überflüssigen" Code bevorzuge.
property SomeProp: integer read FSomeProp write FSomeProp;
|
AW: Frage zu Propertys
Zitat:
Delphi-Quellcode:
Aber der wahre Unterschied sieht man im Erzeugten Laufzeitcode
type
TPerson = class private FVorname, FNachname: string; published property Vorname: string read FVorname write FVorname; end; TPerson2 = class private FVorname, FNachname: string; public proedure setVorname( AValue: string); published property Vorname: string read FVorname write setVorname; end; ... var p1: TPerson; p2: TPerson2; ... //Kein Unterschied bei der Verwendung, nur mehr Code p1.Vorname := 'Franz'; p2.Vorname := 'Otto';
Delphi-Quellcode:
wird zu
p1.Vorname := 'Franz';
Delphi-Quellcode:
p1.FVorname := 'Franz';
Delphi-Quellcode:
wird zu
p2.Vorname := 'Otto';
Delphi-Quellcode:
->
p2.setVorname( 'Otto');
Delphi-Quellcode:
Im Endeffekt wird das selber gemacht nur hat man anstatt einer normalen Wertzuweisung noch einen Methodenaufruf dazwischen.
p2.FVorname := 'Otto';
Und dieser ist imho überflüssig. Interfaces sind sinnvoll aber nicht immer und für Alles. |
AW: Frage zu Propertys
Zitat:
|
AW: Frage zu Propertys
Zitat:
Die Frage die der TE stellte, war: "Aber was spricht denn gegen property Name: String read FName write FName; ?" Und mein geschilderter Anwendungsfall wäre somit ein Punkt, der m.E. dagegen spricht :> |
AW: Frage zu Propertys
@alda
Ich will jetzt nicht mit dem Spruch kommen, dass alles was Delphi-Entwickler vormachen gleich richtig ist, aber guckt man sich die Delphi-Units an, wird nirgendwo über Setter oder Getter auf eine Feldvariable zugegriffen. Die Regel ist
Delphi-Quellcode:
. Nur wenn noch etwas Code dazukommt wird es anders gemacht.
property SomeProp: integer read FSomeProp write FSomeProp;
Der Entwickler macht es also vor, warum soll man es anders machen? |
AW: Frage zu Propertys
So stell ich mir eine lebhafte Diskussion vor :) :thumb:
|
AW: Frage zu Propertys
Zitat:
kann mir jemand mal erklären wie das gemeint ist mit den Interfaces und der Testbarkeit? Eine Klasse mit einer Property, die direkt auf die Feldvariable schreibt/liest, kann man nicht testen? Und es geht doch um eine Klasse, wie kommen da jetzt Interfaces ins Spiel? |
AW: Frage zu Propertys
Er meint keine Properties und dafür nur Getter/Setter, die er durch Interfaces definiert. ( Die Implementierung/Attribute ist/sind dann black box)
|
AW: Frage zu Propertys
Ist es nicht letztlich eine Frage des Anwendungsfalles - wie so oft ?
Ich persönlich benutze absolut überhaupt keine Interfaces, weil es schlicht keine Notwendigkeit bisher dazu gab (Faulheit in Sachen Speicher nicht mehr freigeben ist keine für mich :lol:). Ergo sind für mich Getter/Setter, die nichts weiter tun, als Werte einzuschreiben bzw. wieder auszulesen absolut überflüssiger Code, der nur Platz und Laufzeit kostet. Folglich habe ich faktisch nur "propf"'s im Code. Ganz anders unser Interface-Mensch, der alles und jeden in ein Interface steckt - der ist gezwungen, Getter/Setter zu haben, selbst wenn sie nur einschreiben bzw. auslesen (was für mich bereits ein Grund ist, Interfaces möglichst zu meiden - unnötigen Code produzieren zu müssen). So hat jeder sein Kreuz zu tragen ;) |
AW: Frage zu Propertys
Zitat:
Interfaces nur um der Interfaces willen ist genauso intelligent wie Setter nur um der Setter willen. |
AW: Frage zu Propertys
Zitat:
Zum Testen wird einfach eine andere Klasse verwendet, welche zusätzliche Debugfeatures enthält oder die immer nur definierte Testdaten liefert, so daß man immer wieder das gleiche Verhalten hat, welches sich leichter testen lässt, da man dann immer das selbe Ergebnis rausbekommt. z.B. du hast einen Parser/Auswertecode, welcher getestet werden soll, dann wird in diesem Fall die Klasse ausgetauscht, welche die zu verarbeitenden Daten liefert. Man kann auch die Anzeigeklasse austauschen, welche die verarbeiteten Daten gleich prüft. Grund: Man testet nur den einen Zwischenteil, da drumrum alles gegen funktionierend Testklassen ausgetauscht wurde. So lässt sich jeder Teil einzeln prüfen und man weiß genau wo der Fehler ist. Schaust du zum Test aber nur auf die Anzeige, dann kann der Fehler sonstwo sein. |
AW: Frage zu Propertys
Zitat:
Zitat:
Zitat:
Zitat:
|
AW: Frage zu Propertys
Zitat:
Deswegen kenn ich mich da nicht aus und frag vllt. dumm. Aber wenn ich statt mit Interfaces mit abstrakten Vorfahren-Klassen arbeite könnte ich doch dagegen testen? Und im Gegensatz zu Interfaces kann es in abstrakten Klassen ja Felder geben und dementsprechend direkt durchgreifende Properties Und wenn ein Nachfahre mal nicht direkt durchgreift, sondern getter und setter hat, merk ich das von aussen noch nicht mal. Aber wie gesagt, kenne Unit-Testing nicht und vermute mal, dass diese Frameworks dafür mit Interfaces arbeiten? |
AW: Frage zu Propertys
Mit einem/mehreren Interfaces kannst du dir eine große Testklasse bauen um dann den Teil zu testen, der diese Interfaces benutzt.
z.B. protokolliert die Testklasse jeden Interface-Aufruf.
Delphi-Quellcode:
Bei einer/mehreren abstrakten Klasse/n geht das eben nicht.
TMockTest = class( TInterfacedObject, IFoo, IBar, IWeiss, IGelb )
... end; |
AW: Frage zu Propertys
Zitat:
![]() Denn Test-Driven Development ist alles andere, als aufwendig ;> Naja also erst einmal kannst Du das nur, wenn alles was zu testen ist (also alles :P) auch vom Basis-Vorfahren implementiert wird. Das bedeutet wiederum, dass Du immer mit dem Typ der Basisklasse arbeiten musst (meineVariable: TBasisklasse) und damit koppelst Du die Verwendung wieder an eine Klasse (dann eben TBasisklasse). Hierfür müsstest Du dann deine Stubklassen für den Test vom Basis-Vorfahren ableiten und musst diese auch immer anpassen, sofern sich etwas (vielleicht irrelevantes für deinen Test) an der Basis-Klasse ändert. Genau für diesen Fall sind eben nunmal Interfaces gedacht, auch wenn es Sprachen gibt, die dieses abstrakte Modell verfolgen (z.B. Python). Vererbung beschreibt nunmal eine gemeinsame Vorgehensweise und ein Interface eben eine gemeinsame Schnittstelle. Und für den Test unterscheidet sich die Vorgehensweise (die Implementierung) nunmal von der, der Basisklasse |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:04 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