Was ist die "puristische" oder "richtige" Methode, um über eine Objektmethode, die keine Getter / Setter-Methode ist, auf die Eigenschaften eines Objekts zuzugreifen?
Ich weiß, dass Sie von außerhalb des Objekts einen Getter / Setter verwenden sollten, aber von innen würden Sie einfach Folgendes tun:
Java:
String property = this.property;
PHP:
$property = $this->property;
oder würdest du tun:
Java:
String property = this.getProperty();
PHP:
$property = $this->getProperty();
Verzeihen Sie mir, wenn mein Java ein wenig abweicht, es ist ein Jahr her, seit ich in Java programmiert habe ...
BEARBEITEN:
Es scheint, dass die Leute davon ausgehen, dass ich nur über private oder geschützte Variablen / Eigenschaften spreche. Als ich OO lernte, wurde mir beigebracht, Getter / Setter für jede einzelne Eigenschaft zu verwenden, auch wenn diese öffentlich war (und tatsächlich wurde mir gesagt, dass ich niemals eine Variable / Eigenschaft öffentlich machen soll). Ich gehe also möglicherweise von Anfang an von einer falschen Annahme aus. Es scheint, dass die Leute, die diese Frage beantworten, vielleicht sagen, dass Sie öffentliches Eigentum haben sollten und dass diese keine Getter und Setter brauchen, was gegen das verstößt, was mir beigebracht wurde und worüber ich gesprochen habe, obwohl das vielleicht als diskutiert werden muss Gut. Das ist wahrscheinlich ein gutes Thema für eine andere Frage ...
Persönlich halte ich es für wichtig, konsequent zu bleiben. Wenn Sie Getter und Setter haben, verwenden Sie diese. Ich würde nur dann direkt auf ein Feld zugreifen, wenn der Accessor viel Overhead hat. Es mag sich so anfühlen, als würden Sie Ihren Code unnötig aufblähen, aber es kann in Zukunft sicherlich eine Menge Kopfschmerzen ersparen. Das klassische Beispiel:
Möglicherweise möchten Sie später die Funktionsweise dieses Felds ändern. Vielleicht sollte es im laufenden Betrieb berechnet werden, oder Sie möchten einen anderen Typ für den Hintergrundspeicher verwenden. Wenn Sie direkt auf Eigenschaften zugreifen, kann eine solche Änderung eine Menge Code in einem einzigen Schritt zerstören.
quelle
Ich bin ziemlich überrascht, wie einstimmig das Gefühl ist
getters
und die Setter sind in Ordnung und gut. Ich schlage den Brandartikel von Allen Holub " Getters And Setters Are Evil " vor. Zugegeben, der Titel ist für den Schockwert, aber der Autor macht gültige Punkte.Wenn Sie
getters
undsetters
für jedes einzelne private Feld haben, machen Sie diese Felder im Wesentlichen so gut wie öffentlich. Es würde Ihnen sehr schwer fallen, den Typ eines privaten Feldes ohne Welligkeitseffekte für jede Klasse zu ändern, die dies nenntgetter
.Darüber hinaus sollten Objekte aus rein OO-Sicht auf Nachrichten (Methoden) reagieren, die ihrer (hoffentlich) Einzelverantwortung entsprechen. Die überwiegende Mehrheit von
getters
undsetters
macht für ihre Bestandteile keinen Sinn;Pen.dispenseInkOnto(Surface)
macht für mich mehr Sinn alsPen.getColor()
.Getter und Setter ermutigen Benutzer der Klasse außerdem, das Objekt nach Daten zu fragen, eine Berechnung durchzuführen und dann einen anderen Wert im Objekt festzulegen, der besser als prozedurale Programmierung bekannt ist. Es wäre besser, wenn Sie dem Objekt einfach sagen würden, dass es das tun soll, was Sie ursprünglich wollten. auch als Information Expert Idiom bekannt.
Getter und Setter sind jedoch notwendige Übel an der Grenze der Ebenen - Benutzeroberfläche, Persistenz usw. Durch den eingeschränkten Zugriff auf die Interna einer Klasse, wie z. B. das Friend-Schlüsselwort von C ++, den paketgeschützten Zugriff von Java, den internen Zugriff von .NET und das Friend-Klassenmuster, können Sie die Sichtbarkeit
getters
und die Setter nur auf diejenigen reduzieren, die sie benötigen.quelle
Dies hängt davon ab, wie die Eigenschaft verwendet wird. Angenommen, Sie haben ein Schülerobjekt mit einer Namenseigenschaft. Sie können Ihre Get-Methode verwenden, um den Namen aus der Datenbank abzurufen, sofern er noch nicht abgerufen wurde. Auf diese Weise reduzieren Sie unnötige Aufrufe der Datenbank.
Angenommen, Sie haben einen privaten Ganzzahlzähler in Ihrem Objekt, der zählt, wie oft der Name aufgerufen wurde. Möglicherweise möchten Sie die Get-Methode nicht innerhalb des Objekts verwenden, da dies zu einer ungültigen Anzahl führen würde.
quelle
PHP bietet eine Vielzahl von Möglichkeiten, um damit umzugehen, einschließlich magischer Methoden
__get
und__set
, aber ich bevorzuge explizite Getter und Setter. Hier ist der Grund:quelle
Vielleicht ;)
Ein anderer Ansatz wäre, eine private / geschützte Methode zu verwenden, um das Abrufen tatsächlich durchzuführen (Caching / db / etc), und einen öffentlichen Wrapper dafür, der die Anzahl erhöht:
PHP:
und dann aus dem Objekt selbst heraus:
PHP:
Auf diese Weise können Sie dieses erste Argument immer noch für etwas anderes verwenden (z. B. das Senden eines Flags, ob hier zwischengespeicherte Daten verwendet werden sollen oder nicht).
quelle
Ich muss hier den Punkt verfehlen, warum sollten Sie einen Getter in einem Objekt verwenden, um auf eine Eigenschaft dieses Objekts zuzugreifen?
Um dies zu Ende zu bringen, sollte der Getter einen Getter nennen, der einen Getter nennen sollte.
Ich würde also sagen, dass der Zugriff auf eine Eigenschaft innerhalb einer Objektmethode direkt ist, insbesondere wenn der Aufruf einer anderen Methode in diesem Objekt (die ohnehin nur direkt auf die Eigenschaft zugreift und sie dann zurückgibt) nur eine sinnlose, verschwenderische Übung ist (oder ich die Frage falsch verstanden habe ).
quelle
Der puristische OO-Weg besteht darin, beides zu vermeiden und dem Gesetz von Demeter zu folgen, indem der Tell Don't Ask- Ansatz verwendet wird.
Anstatt den Wert der Objekteigenschaft zu erhalten, die die beiden Klassen eng miteinander verbindet , verwenden Sie das Objekt als Parameter, z
Wenn die Eigenschaft ein nativer Typ war, z. B. int, verwenden Sie eine Zugriffsmethode und benennen Sie sie für die Problemdomäne, nicht für die Programmierdomäne.
Auf diese Weise können Sie die Kapselung und alle Nachbedingungen oder abhängigen Invarianten beibehalten. Sie können auch die Setter-Methode verwenden, um Vorbedingungen oder abhängige Invarianten beizubehalten. Fallen Sie jedoch nicht in die Falle, diese Setter zu benennen, sondern kehren Sie zur Benennung des Hollywood-Prinzips zurück, wenn Sie das Idiom verwenden.
quelle
Es ist besser, die Zugriffsmethoden auch innerhalb des Objekts zu verwenden. Hier sind die Punkte, die mir sofort einfallen:
Dies sollte im Interesse der Konsistenz mit Zugriffen von außerhalb des Objekts erfolgen.
In einigen Fällen können diese Zugriffsmethoden mehr als nur den Zugriff auf das Feld ermöglichen. Sie könnten eine zusätzliche Verarbeitung durchführen (dies ist jedoch selten). Wenn dies der Fall ist, würde ein direkter Zugriff auf das Feld bedeuten, dass Ihnen diese zusätzliche Verarbeitung fehlt, und Ihr Programm könnte schief gehen, wenn diese Verarbeitung während dieser Zugriffe immer durchgeführt werden soll.
quelle
Wenn Sie mit "puristisch" "die meiste Kapselung" meinen, deklariere ich normalerweise alle meine Felder als privat und verwende dann "this.field" innerhalb der Klasse selbst. Für andere Klassen, einschließlich Unterklassen, greife ich mithilfe der Getter auf den Instanzstatus zu.
quelle
Ich habe festgestellt, dass die Verwendung von Setzern / Gettern meinen Code leichter lesbar gemacht hat. Ich mag auch das Steuerelement, das es gibt, wenn andere Klassen die Methoden verwenden und wenn ich die Daten ändere, wird die Eigenschaft gespeichert.
quelle
Private Felder mit öffentlichen oder geschützten Eigenschaften. Der Zugriff auf die Werte sollte über die Eigenschaften erfolgen und in eine lokale Variable kopiert werden, wenn sie in einer Methode mehrmals verwendet werden. Wenn und NUR, wenn Sie den Rest Ihrer Anwendung so vollständig optimiert, gerockt und auf andere Weise optimiert haben, dass der Zugriff auf Werte durch Durchlaufen der zugehörigen Eigenschaften zu einem Engpass geworden ist (und das wird NIEMALS passieren, wie ich garantiere), sollten Sie überhaupt anfangen zu erwägen, dass etwas anderes als die Eigenschaften ihre Hintergrundvariablen direkt berühren.
.NET-Entwickler können automatische Eigenschaften verwenden, um dies zu erzwingen, da Sie die Entwurfsvariablen zur Entwurfszeit nicht einmal sehen können.
quelle
Es hängt davon ab, ob. Es ist mehr ein Stilproblem als alles andere, und es gibt keine harte Regel.
quelle
Ich kann mich irren, weil ich Autodidakt bin, aber ich benutze NIEMALS öffentliche Eigenschaften in meinen Java-Klassen, sie sind immer privat oder geschützt, so dass externer Code von Gettern / Setzern abgerufen werden muss. Es ist besser für Wartungs- / Änderungszwecke. Und für Code innerhalb der Klasse ... Wenn die Getter-Methode trivial ist, verwende ich die Eigenschaft direkt, aber ich verwende immer die Setter-Methoden, da ich auf Wunsch leicht Code zu Feuerereignissen hinzufügen kann.
quelle
Wenn ich die Eigenschaft nicht bearbeite, verwende ich eine öffentliche Methode, es
get_property()
sei denn, es handelt sich um einen besonderen Anlass, z. B. ein MySQLi-Objekt in einem anderen Objekt. In diesem Fall mache ich die Eigenschaft einfach öffentlich und bezeichne sie als$obj->object_property
.Innerhalb des Objekts ist es für mich immer $ this-> property.
quelle
Nun, mit der Standardimplementierung der C # 3.0-Eigenschaften scheint die Entscheidung für Sie getroffen zu sein. Sie MÜSSEN die Eigenschaft mit dem (möglicherweise privaten) Eigenschaftssetter festlegen.
Ich persönlich benutze das private Member-Behind nur, wenn dies nicht dazu führen würde, dass das Objekt in einen weniger wünschenswerten Zustand fällt, z. B. beim Initialisieren oder beim Caching / Lazy Loading.
quelle
Ich mag die Antwort von cmcculloh , aber die Antwort von Greg Hurlman scheint die richtigste zu sein . Verwenden Sie immer Getter / Setter, wenn Sie sie von Anfang an verwendet haben und / oder Sie daran gewöhnt sind, mit ihnen zu arbeiten.
Abgesehen davon finde ich persönlich, dass die Verwendung von Getter / Setter das Lesen des Codes und das spätere Debuggen erleichtert.
quelle
Wie in einigen Kommentaren angegeben: Manchmal sollten Sie, manchmal sollten Sie nicht. Das Tolle an privaten Variablen ist, dass Sie alle Orte sehen können, an denen sie verwendet werden, wenn Sie etwas ändern. Wenn Ihr Getter / Setter etwas tut, das Sie brauchen, verwenden Sie es. Wenn es egal ist, entscheiden Sie.
Der umgekehrte Fall könnte gemacht werden, dass wenn Sie den Getter / Setter verwenden und jemand den Getter / Setter ändert, er alle Stellen analysieren muss, an denen der Getter und der Setter intern verwendet werden, um festzustellen, ob etwas durcheinander kommt.
quelle