Code entwickelt sich . private
ist ideal, wenn Sie brauchen den Schutz der Daten von Mitgliedern . Letztendlich sollten alle Klassen eine Art "Miniprogramme" sein, die eine klar definierte Schnittstelle haben. dass man nicht einfach an den Interna des Systems herumschrauben kann .
Davon abgesehen, Software-Entwicklung geht es nicht darum, die endgültige Version des Kurses so hinzustellen, als ob man eine gusseiserne Statue beim ersten Versuch drücken würde. Während man damit arbeitet, ist der Code eher wie Ton. Sie entwickelt sich weiter während Sie es entwickeln und mehr über den Problembereich erfahren, den Sie lösen wollen. Während der Entwicklung können Klassen miteinander interagieren, als sie sollten (Abhängigkeit, die Sie planen, auszugleichen), miteinander verschmelzen oder sich aufspalten. Ich denke, die Debatte läuft darauf hinaus, dass die Leute nicht religiös schreiben wollen
int getVar() const { return var ; }
Sie haben also:
doSomething( obj->getVar() ) ;
Anstelle von
doSomething( obj->var ) ;
Es ist nicht nur getVar()
visuell verrauscht, es erweckt den Eindruck, dass gettingVar()
ein komplexerer Prozess ist, als er in Wirklichkeit ist. Wie Sie (als Klassenschriftsteller) die Unantastbarkeit der var
ist besonders verwirrend für einen Benutzer Ihrer Klasse, wenn sie einen Passthru-Setter hat - dann sieht es so aus, als ob Sie diese Gates aufstellen, um etwas zu "schützen", das Sie für wertvoll halten (die Unantastbarkeit von var
), aber selbst Sie räumen ein var
Die Möglichkeit, dass jeder einfach reinkommt und die Daten abruft, macht den Schutz des Unternehmens wertlos. set
var
zu jedem beliebigen Wert, ohne dass Sie auch nur einen Blick darauf werfen, was sie tun.
Ich programmiere also wie folgt (unter der Annahme eines "agilen" Ansatzes - d.h., wenn ich Code schreibe, ohne zu wissen genau was es tun wird/keine Zeit oder Erfahrung für die Planung einer aufwendigen Wasserfallschnittstelle hat):
1) Beginnen Sie mit allen öffentlichen Mitgliedern für grundlegende Objekte mit Daten und Verhalten. Aus diesem Grund werden Sie in meinem gesamten C++ "Beispiel"-Code feststellen, dass ich struct
anstelle von class
überall.
2) Wenn das interne Verhalten eines Objekts für ein Datenelement komplex genug wird (z.B. wenn es eine interne std::list
in irgendeiner Reihenfolge), werden Funktionen vom Typ Accessor geschrieben. Da ich selbst programmiere, setze ich nicht immer das Mitglied private
sofort, aber irgendwann im Laufe der Entwicklung der Klasse wird das Mitglied "befördert" zu entweder protected
o private
.
3) Klassen, die vollständig ausgearbeitet sind und strenge Regeln für ihre Interna haben (z.B. sie genau wissen, was sie tun, und Sie nicht mit seinen Interna "fummeln" (Fachbegriff) dürfen, erhalten die class
Bezeichnung, standardmäßig private Mitglieder, und nur einige wenige Mitglieder dürfen public
.
Ich finde, dieser Ansatz ermöglicht es mir zu vermeiden, dort zu sitzen und religiös zu schreiben Getter/Setter, wenn eine Menge von Daten Mitglieder migriert werden, verschoben, etc. während der frühen Phasen der Entwicklung einer Klasse.
8 Stimmen
@Dean J: D stackoverflow.com/search?q=getters+setters
10 Stimmen
Natürlich ist beides gleich schlecht, wenn das Objekt keine zu ändernde Eigenschaft benötigt. Ich würde lieber alles privat machen, und dann Getter hinzufügen, wenn es nützlich ist, und Setter, wenn es nötig ist.
31 Stimmen
Google "accessors are evil"
42 Stimmen
"Accessors sind böse", wenn Sie funktionalen Code oder unveränderliche Objekte schreiben. Wenn Sie zustandsbehaftete, veränderbare Objekte schreiben, dann sind sie ziemlich wichtig.
23 Stimmen
Erzählen, nicht fragen. pragprog.com/articles/tell-dont-ask
2 Stimmen
Mit Ausnahme von 6 und 8 würde ich es wagen zu sagen, dass keiner dieser Punkte in 99 % der Fälle zur Anwendung kommt. Dennoch würde ich gerne Java verwenden
String s = employee.name()
yemployee.name("oscar")
anstelle von getName() setName()1 Stimmen
@Oscar Reyes, ja, ich stimme zu, dass 6 und 8 meiner Erfahrung nach die beiden häufigsten sind. Das heißt, ich bevorzuge immer noch nicht mit der C#ish Syntax; mein alter Mann Gehirn wird verwirrt.
4 Stimmen
Ich bin überrascht, dass niemand über die Datensynchronisation spricht. Angenommen, Sie verwenden
public String foo;
es ist nicht fadensicher! Stattdessen können Sie definierenget
terset
ters mit Synchronisierungstechniken, um die Untreue von Daten zu vermeiden [d.h. ein anderer Thread, der das foo durcheinanderbringt]. Ich hielt es für erwähnenswert.3 Stimmen
@goldenparrot: Meistens ist die Synchronisierung einzelner Zugriffe auf ein Objekt viel zu ineffizient oder sogar anfällig für Synchronisierungsprobleme (wenn man mehrere Eigenschaften eines Objekts ändern muss sogleich ). IME, müssen Sie oft Operationen als Ganzes verpacken, die mehrere Zugriffe auf ein Objekt durchführen. Das kann nur durch Synchronisation auf der Seite der Benutzer eines Typs erreicht werden.
1 Stimmen
Fassen Sie Ihre Lieblingsstellen aus allen Antworten nicht in der Frage selbst zusammen. Dies ist eine Seite für Fragen und Antworten, kein Forum.
3 Stimmen
@ErikReppen was sollte ich lesen, um OOP überhaupt zu verstehen?
0 Stimmen
Es gibt auch das sehr wichtige Problem der gemeinsamen Nutzung von Code mit anderen, wenn Sie Objektfelder als Teile der externen Schnittstelle behandeln, die andere Leute nutzen können, dann könnte es unmöglich sein, das Feld in eine Funktion zu ändern, ohne Änderungen im Code anderer Leute zu zerstören.
0 Stimmen
@ErikReppen Danke für den Link, ich arbeite daran, zu verstehen, was OOP sein soll, aber es erweist sich als schwierig bei der Menge an Fehlinformationen, die im Umlauf sind. P.S. Ich finde auch, dass wikipedia eine der besten Quellen in vielen wissenschaftlichen Bereichen ist.
3 Stimmen
@TimoHuovinen es geht darum, nicht herausfinden zu müssen, welche von 500 Funktionen tatsächlich einen Wert ändert. Man macht einen Wert oder eine Reihe von Werten zu etwas, für das man verantwortlich ist, und nicht zu etwas, das man auf eine Param/Return-Achterbahn setzen kann. Vermeiden Sie Vanilla Getters/Setters und öffentliche Eigenschaften, und Sie werden oft feststellen, dass Sie innehalten und darüber nachdenken müssen, wie Sie Ihre Anwendung auf eine Art und Weise modellieren können, die in der Regel einfacher zu lesen, zu ändern, in großen Teilen wiederzuverwenden, zu debuggen ist und der Sie vertrauen können, ohne sie bis ins Mark zu testen. Java und C# haben OOP übertrieben und es dann aufgegeben, IMO.
1 Stimmen
In einem weiteren Artikel wird versucht, Leitlinien für die Verwendung von Gettern und Settern aufzustellen: Öffentliche oder private Mitgliedsvariablen? Das YAGNI-Prinzip leitet uns dazu an, erst dann Konstrukte hinzuzufügen, wenn wir wirklich wissen, dass wir sie brauchen werden.
0 Stimmen
Punkte 2, 3 (?), 4, 5 und 8: vorläufig ja. Die anderen: definitiv nein. Was spielt es für eine Rolle, ob Sie Python, C#, Ruby, Objective-C oder einen Esolang verwenden, wenn Ihr Code einfach, elegant und leicht wartbar/erweiterbar ist?
2 Stimmen
666 Upvotes scheinen kein Zufall zu sein
2 Stimmen
"Man kann leicht erkennen, dass Sie Python nicht benutzt haben" sollte eigentlich die Nr. 1 sein!
0 Stimmen
@Kaiserludi Könnten Sie erläutern, inwiefern das eine gute Sache ist?
0 Stimmen
@DeanJ Könnten Sie bitte die Nummer 10 erklären?
0 Stimmen
@Joshua: Das war nur ein Scherz, denn der Autor hat das eindeutig nicht ernst gemeint, als er es auf die Liste gesetzt hat.
2 Stimmen
11. T
1 Stimmen
Eine kürzlich gestellte Frage hat mich an einen weiteren Grund für Set-Methoden erinnert: die Möglichkeit, eine Änderung der Eigenschaft .