Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Property oder Feld in der eigenen Klasse nutzen (https://www.delphipraxis.net/180965-property-oder-feld-der-eigenen-klasse-nutzen.html)

sahimba 3. Jul 2014 18:18

Delphi-Version: 2010

Property oder Feld in der eigenen Klasse nutzen
 
Moinsen,

hier auf Arbeit geht es gerade um die Frage, ob ich innerhalb "meiner eigenen" Klasse auf meine eigenen Felder direkt zugreifen darf oder dies auch dort über die zur Verfügung stehenden Properties tun sollte. Folgendes Beispiel soll das verdeutlichen; die Methode "DoSomething" ist hier von Interesse:

Delphi-Quellcode:
type
  TSomeClass = class(TObject)
  private
    FData: String;
    function GetData: String;
    procedure SetData(const Value: String);
  public
    procedure DoSomething;
    property Data: String read GetData write SetData;
  end;

{ TSomeClass }

function TSomeClass.GetData: String;
begin
  Result := FData;
end;

procedure TSomeClass.SetData(const Value: String);
begin
  FData := Value;
end;

procedure TSomeClass.DoSomething;
begin
  FData := 'Hello';
  // versus
  Data := 'Hello';
end;
Zwar ist die Antwort wohl, wie so oft, "es kommt darauf an", mir selber beantworte ich die Frage allerdings sehr eindeutig. Mein Kollege sieht das allerdings gänzlich anders. Und da möchte ich das einfach mal so in die Runde werfen um für meine Position (welche dasist verrate ich nicht...) noch einige Argumente zu finden ;)

Sir Rufo 3. Jul 2014 18:23

AW: Property oder Feld in der eigenen Klasse nutzen
 
Nein es kommt nicht darauf an.

Eine Klasse darf intern mit allem rumspielen wie sie möchte um das Erscheinungsbild nach aussen hin zu wahren. Darauf kommt es einzig und alleine an, ob die Klasse von aussen so reagiert, wie das erwartet wird. Wie das intern erreicht wird spielt keine Geige.

Oft wird sogar ganz bewusst das Feld genommen und nicht die Eigenschaft, weil man ganz bewusst den Getter und Setter umgehen will/muss.
Delphi-Quellcode:
TFoo = class
private
  FBar : TBar;
  function GetBar : TBar;
public
  property Bar : TBar read GetBar;
  procedure DoSomething;
end;

function TFoo.GetBar : TBar;
begin
  if not Assigned( FBar ) then
    FBar := TBar.Create;
  Result := FBar;
end;

procedure TFoo.DoSomething;
begin
  if Assigned( FBar ) then
    FBar.DoSomethingDifferent;
end;

Der schöne Günther 3. Jul 2014 18:28

AW: Property oder Feld in der eigenen Klasse nutzen
 
Für "use getters and setters inside class" bietet das Internet eine Vielzahl an Meinungen.

Mein persönlicher Hauptgrund Properties/Getter und Setter auch innerhalb der eigenen Klasse zu verwenden ist schlichtweg, dass sich die Implementation, etwas zu "getten" oder "setten" gerne mal nachträglich ändert. Greife ich nun mal direkt auf das Feld, dann irgendwo mit den Gettern und Settern, dann irgendwo wieder so auf das Feld zu habe ich etliche Stellen die ich anpassen muss.

Bleibt man konkret bei der Benutzung der Getter und Setter hat man nur diese beiden Stellen anzupassen.

Klar kann man Stellen haben wo man die Logik in den Gettern/Settern umgehen muss, aber auch nur dort benutze ich die Properties nicht. "Oft" kann ich mir das nicht vorstellen, aber wir sind wohl alle zu verschieden 8-)

Sir Rufo 3. Jul 2014 18:32

AW: Property oder Feld in der eigenen Klasse nutzen
 
Innerhalb der Klasse sehe ich die Getter und Setter (Verhalten) und kann je nach gewünschtem Verhalten auf das Feld oder Getter und Setter zugreifen.

Eine pauschale Aussage wie nur Getter und Setter oder nur direkt auf die Felder ist Schwachfug, sondern es geht einzig und alleine um das Verhalten der Klasse. Das muss passen, alles andere ist etwas für den Mate-Teekreis und die Problemkerze auf dem Jute-Platzset.

sahimba 3. Jul 2014 18:35

AW: Property oder Feld in der eigenen Klasse nutzen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264335)
Innerhalb der Klasse sehe ich die Getter und Setter (Verhalten) und kann je nach gewünschtem Verhalten auf das Feld oder Getter und Setter zugreifen.

Getter/Setter können virtual sein.

Sir Rufo 3. Jul 2014 18:42

AW: Property oder Feld in der eigenen Klasse nutzen
 
Zitat:

Zitat von sahimba (Beitrag 1264336)
Zitat:

Zitat von Sir Rufo (Beitrag 1264335)
Innerhalb der Klasse sehe ich die Getter und Setter (Verhalten) und kann je nach gewünschtem Verhalten auf das Feld oder Getter und Setter zugreifen.

Getter/Setter können virtual sein.

Ja und jetzt? Damit die Frage für diesen Fall Sinn macht, muss die Klasse ja auch das Field kennen und Getter und Setter überschreiben (wie kommt man sonst von aussen an den Wert oder wo ist da die Wahl).

Wenn ich nur Getter/Setter habe, dann reduziert sich doch irgendwie die Wahlmöglichkeit auf Getter/Setter oder Getter/Setter :stupid:

himitsu 3. Jul 2014 18:44

AW: Property oder Feld in der eigenen Klasse nutzen
 
Es kommt drauf an, was für einen Zugriff man auf diesen Wert braucht
und dementsprechend entscheidet man sich entweder geziehlt für den direkten zugriff, weil man das Verhalten des Getter/Setter "umgehen" muß
oder man geht eben auch über die Getter/Setter das Property.

Sagen wir es einfach mal so:

Am Einfachsten greift man ebenfalls "immer" über das Property drauf zu, auch von innen
und da wo es sein "muß" (1), geht man eben direkt auf das Feld.

1:
- Geschwindigkeit, da man oft zugreift und man die Prüfung, welche z.B. im Getter drin ist, schon "einmal" ausreichend am Anfang der Routine gemacht hat
- ebenso beim Setter ... z.B. das Refresh da drin, kann man ja intern z.B. auch nur einmal am Ende der Routine machen
- im Setter/Getter wird irgendwas ausgelöst, welches an dieser Stelle nicht gemacht werden soll/darf
- ...



Und nein, dein Beispiel ist bissl blöd, denn Getter und Setter machen absolut nichts, weswegen man das Property dort auch direkt auf das Feld zugreifen lassen kann.
Aber beüglich der Aussage, ob man nun direkt auf das Feld oder auf Getter/Setter das Property zugreifen soll, ändert sich nichts.

Man muß sich eben einfach situationsbedingt entscheiden, ob man
- direkt unbedingt auf das Feld gehen muß
- oder ob man auf das Property gehen muß, da dort drin noch was ausgelöst wird, welches ausgelöst werden muß, was man aber nicht nochmal machen will (wenn man über das Feld ginge)
- oder ob man auch das Property nehmen kann, da es praktisch keinen großen Unterschied macht (wenn es egal ist, dann meistens das Property)
- und manchmal nehme ich intern auch direkt den Setter, da ich zwar den Weg des Property nehmen will, aber mir an der Stelle die Syntax des Prozeduraufrufs lieber ist, weil es im Codefluss einfach "schöner" aussieht :oops:

Dejan Vu 4. Jul 2014 08:59

AW: Property oder Feld in der eigenen Klasse nutzen
 
Eigentlich ist die Antwort doch ganz einfach: Der Zugriff erfolgt innerhalb der Klasse immer über die Property, außer, ich muss bewusst die Getter/Setter-Logik. Dann verwende ich direkt den backing store, also das private Feld. Und wenn man sich das genau überlegt, dann ist das auch nur an einer einzigen Stelle sinnvoll: Beim Initialisieren des Wertes. Und auch das sollte nur an einer Stelle in der Klasse erfolgen.
Wenn man an mehreren Stellen den die Propertyogik umgeht, ist mit an Sicherheit grenzender Wahrscheinlichkeit etwas faul im Design und man sollte sich genau überlegen, ob man mit diesem design flaw weiterprogrammiert, oder erst einmal aufräumt. Das kann wenigstens über eine Methode 'InitializeProperty' erfolgen, um wenigstens das DRY einzuhalten, aber auch hier sollte ein mehrfacher Aufruf zu selbstkritischen Designfragen führen.

PS: Wieso schreibe ich das, wo doch himitsu fast das Gleiche gesagt hat? :stupid:

himitsu 4. Jul 2014 10:01

AW: Property oder Feld in der eigenen Klasse nutzen
 
Und wenn man bedenkt, daß Sichtbarkeiten innerhalb einer Unit alle praktisch mindestens wir public aussehen, selbst klassenübergreifend, dann sollte man sich eventuell auch mal an
Delphi-Quellcode:
strict private
und
Delphi-Quellcode:
strict protected
gewöhnen, um da nicht ausversehn das private Feld zu nutzen, anstatt dem Property, wenn man aus der Unit oder einer anderen enthaltenen Klasse drauf zugreift.

DeddyH 4. Jul 2014 10:20

AW: Property oder Feld in der eigenen Klasse nutzen
 
Das sollte man IMO sowieso generell tun, sonst wundert man sich später, wenn man eine Klasse in eine eigene Unit verschiebt und diese plötzlich nicht mehr funktioniert. Außerdem wirkt die Code-Vervollständigung gleich viel aufgeräumter ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:41 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