Wo ich arbeite, sehe ich viele Klassen, die solche Dinge tun:
public class ClassThatCallsItsOwnGettersAndSetters {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public void methodWithLogic() {
setField("value");
//do stuff
String localField = getField();
//do stuff with "localField"
}
}
Wenn ich das von Grund auf neu geschrieben hätte, hätte ich methodWithLogic()
stattdessen folgendes geschrieben :
public class ClassThatUsesItsOwnFields {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public void methodWithLogic() {
field = "value";
//do stuff
//do stuff with "field"
}
}
Ich glaube, wenn die Klasse ihre eigenen Getter und Setter aufruft, ist der Code schwieriger zu lesen. Für mich bedeutet das fast , dass in diesem Methodenaufruf komplexe Logik vor sich geht, obwohl dies in unserem Fall so gut wie nie der Fall ist. Wenn ich unbekannten Code debugge, wer sagt dann, dass der Fehler bei dieser Methode keine Nebenwirkung hat? Mit anderen Worten, ich muss auf dem Weg zum Verständnis des Codes viele Abstecher machen.
Gibt es Vorteile für die erste Methode? Ist die erste Methode eigentlich besser?
java
object-oriented
programming-practices
Daniel Kaplan
quelle
quelle
Antworten:
Ich werde nicht sagen, was besser oder schlechter ist, weil das teilweise von Ihrer Situation abhängt (meiner Meinung nach). Bedenken Sie jedoch, dass Ihre Getter und Setter die Implementierung später möglicherweise ändern. Wenn Sie diese umgehen, wird diese Logik übersprungen.
Was passiert zum Beispiel, wenn Sie später einigen Setterfeldern ein "Dirty" -Flag hinzufügen? Wenn Sie Ihre Setter in Ihrem internen Code anrufen, setzen Sie das Dirty-Flag, ohne einen anderen Code zu ändern. In vielen Situationen wäre dies eine gute Sache.
quelle
setField()
von Anfang an angerufen haben, haben Sie gerade einen Fehler gemeldet.Ein direkter Anruf beim Setter ist an sich kein Problem. Die Frage sollte wirklich lauten: Warum hat unser Code überall Setter?
Veränderbare Klassen sind ein gefährliches Spiel, insbesondere wenn die Klasse selbst ihren eigenen Zustand verwaltet. Überlegen Sie, wie viele dieser Setter wirklich existieren müssen. Wie viele können im Konstruktor festgelegt werden und werden dann vollständig von der Klasse selbst eingekapselt?
Wenn das Feld extern einstellbar sein muss, fragen Sie sich, ob die Methode mit Logik vorhanden sein soll. Ist Ihre Klasse selbst wirklich nur eine Daten- / Statusklasse? Hat diese Klasse mehr als eine Verantwortung?
Versteht mich nicht falsch, es wird Fälle geben, in denen dies in Ordnung ist. Ich sage nicht, dass Sie Setter auf Klassen mit Logik vollständig beseitigen sollten. Dies sollte jedoch die Ausnahme und nicht die Regel sein. Und in diesen wenigen Fällen sollte es offensichtlich sein, auf welche direkt zugegriffen werden kann.
quelle
Ja, die Methoden Ihrer Klasse sollten die Getter und Setter aufrufen. Der springende Punkt beim Schreiben von Gettern und Setzern ist die Zukunftssicherheit. Sie können jede Eigenschaft zu einem Feld machen und die Daten den Benutzern der Klasse direkt zur Verfügung stellen. Der Grund, warum Sie die Getter und Setter erstellen, liegt nicht unbedingt in der komplexen Logik, sondern darin, dass die Schnittstelle in Zukunft nicht kaputt geht, wenn Sie sie hinzufügen müssen.
quelle
someField=newValue; refresh();
Wenn die Methode das Festlegen mehrerer Felder zulässt, würde der Aufruf von Setters zum Schreiben dieser Felder redundante "Aktualisierungs" -Operationen verursachen. Wenn Sie alle Felder schreiben und dannrefresh()
einmal aufrufen , kann dies zu einem effizienteren und reibungsloseren Betrieb führen.Um Ihre Fragen in einem Wort zu beantworten, ja.
Wenn eine Klasse ihre eigenen Getter und Setter aufruft, erhöht dies die Erweiterbarkeit und bietet eine bessere Basis für zukünftigen Code.
Sagen Sie, Sie haben so etwas:
Wenn Sie die Setter für Jahr und Marke aufrufen, werden möglicherweise keine Funktionen hinzugefügt. Was ist jedoch, wenn Sie den Settern eine Eingabevalidierung hinzufügen möchten?
quelle
Eine Sache, die nicht erwähnt wurde, ist, dass Getter und Setter (wie alle Methoden) in Java virtuell sind. Dies fügt eine weitere Funktion hinzu, um sie immer in Ihrem Code zu verwenden. Ein anderer Benutzer könnte Ihre Klasse erweitern und Ihre Getter und Setter überschreiben. Ihre Basisklasse würde dann die Daten der Unterklasse anstelle ihrer eigenen verwenden. In einer Sprache, in der Sie virtuelle Funktionen explizit markieren, ist dies sehr viel praktischer, da Sie vorhersagen und deklarieren können, mit welchen Funktionen dies durchgeführt werden kann. In Java müssen Sie sich dessen immer bewusst sein. Wenn es erwünscht ist, ist es eine gute Sache, sie in Ihrem Code zu verwenden, ansonsten nicht so sehr.
quelle
Wenn Sie versuchen, etwas zu erreichen, das von der öffentlichen Schnittstelle bereitgestellt wird, verwenden Sie die Getter / Setter.
Als Eigentümer / Entwickler der Klasse dürfen Sie jedoch auf die privaten Bereiche Ihres Codes zugreifen (innerhalb der Klasse natürlich), aber Sie sind auch dafür verantwortlich, die Gefahren zu mindern.
Vielleicht haben Sie einen Getter, der eine interne Liste durchläuft, und Sie möchten den aktuellen Wert abrufen, ohne den Iterator zu erhöhen. Verwenden Sie in diesem Fall die private Variable.
quelle
Ja. Getter und Setter stellen den Status dar. Drehen Sie also diese Frage um. Möchten Sie mehrere Möglichkeiten verfolgen, den Status eines Objekts auf dieselbe Weise zu ändern, sofern dies nicht erforderlich ist?
Je weniger Dinge Sie im Auge behalten müssen, desto besser ist es, mit unveränderlichen Objekten leichter umzugehen.
Bedenken Sie, dass nichts Sie daran hindert, sowohl ein öffentliches Feld als auch einen öffentlichen Getter / Setter zu haben - aber was würden Sie gewinnen?
Es kann gelegentlich wünschenswert oder sogar notwendig sein, aus einem oder mehreren Gründen direkt auf das Feld zuzugreifen. Sie sollten sich davor nicht scheuen, wenn es passiert. Aber Sie sollten es wirklich nur tun, wenn dies einen definierten Nutzen hat.
quelle
Beide Methoden haben ihre Anwendungsfälle. Da der öffentliche Setter den Feldwert (und / oder die gebundenen Werte) konsistent hält, sollten Sie den Setter verwenden, wenn Ihre Methodenlogik diese Konsistenzlogik nicht beeinträchtigt. Wenn Sie nur Ihre "Eigenschaft" festlegen, verwenden Sie Setter. Auf der anderen Seite gibt es Situationen, in denen Sie direkten Zugriff auf einige Felder benötigen, z. B. Massenvorgänge mit Heavy Setter oder Vorgänge, bei denen das Setter-Konzept zu einfach ist.
Es liegt in Ihrer Verantwortung, für Einheitlichkeit zu sorgen. Setter tut dies per Definition, kann jedoch keine komplexen Fälle abdecken.
quelle
Ich würde nein sagen ..
Wenn Ihre Getter / Setter nur abrufen und festlegen (keine verzögerte Initialisierung, keine Überprüfungen usw.), dann verwenden Sie einfach Ihre Variablen. Wenn Sie in Zukunft Ihre Getter / Setter ändern, können Sie sehr gut Ihre ändern
methodWithLogic()
(weil sich Ihre Klasse ändert), und Sie können einen Getter / Setter anstelle einer direkten Zuweisung aufrufen. Sie können diesen Aufruf für den Getter / Setter dokumentieren (da es ungewöhnlich ist, einen Getter / Setter aufzurufen, wenn der Rest Ihres Klassencodes direkt die Variable verwendet).Die JVM leitet häufige Anrufe an Getter / Setter weiter. Es ist also nie ein Leistungsproblem. Der Vorteil der Verwendung von Variablen ist die Lesbarkeit und meiner Meinung nach würde ich mich dafür entscheiden.
Hoffe das hilft..
quelle