Getter-Namenskonvention: GetXy() vs. xy()
-
Zwei mögliche Namenskonventionen für Funktionen:
// 1: GetXy(), SetXy() std::size_t GetSize() const; Vector2 GetScale() const; void SetScale(Vector2 scale); void Scale(Vector2 factors); Transform GetTransform() const; bool IsOpen() const;
// 2: xy(), setXy() std::size_t size(); // Vorteil: STL-konform Vector2 scale(); // Vorteil: Simplere Ausdrücke void setScale(Vector2 scale); void scale(Vector2 factors); // Nachteil: Überladung kann verwirren Transform transform() const; // Nachteil: Klingt nach Verb bool open() const; // "
Kurz gesagt hat die 2. Konvention den Vorteil, dass z.B.
clock.elapsed().seconds()
stattclock.GetElapsedTime().GetSeconds()
geschrieben werden kann, zudem sind Methoden wiebegin()
,end()
,swap()
,size()
gleich wie in der STL benannt. Nachteil ist, dass durch fehlendes "Get"-Präfix unklar wird, dass es sich um Getter handelt. In gewissen Fällen muss von der Konvention abgewichen werden, weil Getter und parameterlose Aktionsfunktionen nicht überladen werden können.Kennt ihr weitere Punkte, die für die eine oder die andere Namenskonvention sprechen? Verwendet ihr eine der beiden?
Ich wäre froh, wenn ihr Grundsatzdiskussionen über die Notwendigkeit von Gettern/Settern sowie allgemeines Blabla wie "Konvention ist egal, Hauptsache man ist konsequent" unterlassen würdet. Mir gehts wirklich um konkrete Vor- und Nachteile, vielen Dank im Voraus!
-
Nexus schrieb:
Transform transform() const; // Nachteil: Klingt nach Verb
Der Fehler rührt daher, dass du deine Klasse nach einem Verb benennst. transformation() wäre doch schon klarer.
bool open() const; // Nachteil: Klingt nach Verb
Wenn du schon STL-Konformität anpreist, warum nicht is_open?
void setScale(Vector2 scale);
void scale(Vector2 factors); // Nachteil: Überladung kann verwirrenAuch hier, schlechte Namen. rescale und scale_with?
-
flameanfechter schrieb:
Der Fehler rührt daher, dass du deine Klasse nach einem Verb benennst.
Nein, "transform" ist auch ein Nomen. In der Grafikprogrammierung ist es zudem der übliche Begriff, um Translation, Rotation und Skalierung zusammenzufassen.
flameanfechter schrieb:
Wenn du schon STL-Konformität anpreist, warum nicht is_open?
Wenn, dann
isOpen()
. Mit STL meinte ich aber Container, Iteratoren und Algorithmen. Und der Vorteil der Konformität besteht darin, dass sich generische Funktionen leichter schreiben lassen. Beistd::fstream
ist das weniger wichtig... Das Problem ist halt wieder, dass gewissebool
-Attribute dann mitisXy()
abgefragt werden, andere nur mitxy()
.flameanfechter schrieb:
Auch hier, schlechte Namen. rescale und scale_with?
rescale()
wäre wirklich eine Idee. Danke!
-
In 99,9% der Fälle können Setter durch etwas aussagekräftigers, wie eine Tatigkeit ersetzen. So zum Beispiel eben rescale statt set_scale, move(_by/_to) statt set_position, etc.
-
314159265358979 schrieb:
In 99,9% der Fälle können Setter durch etwas aussagekräftigers, wie eine Tatigkeit ersetzen. So zum Beispiel eben rescale statt set_scale, move(_by/_to) statt set_position, etc.
Das macht es doch auch nicht besser, wenn ich eine unbekannte Klasse sehe und getPosition, dann frage ich mich erst mal, warum gibt es kein setPosition. Irgendwie sieht das nur nach, Getter und Setter sind böse, also nennen wir sie anders, aus.
-
behindblueeyes schrieb:
314159265358979 schrieb:
In 99,9% der Fälle können Setter durch etwas aussagekräftigers, wie eine Tatigkeit ersetzen. So zum Beispiel eben rescale statt set_scale, move(_by/_to) statt set_position, etc.
Das macht es doch auch nicht besser, wenn ich eine unbekannte Klasse sehe und getPosition, dann frage ich mich erst mal, warum gibt es kein setPosition. Irgendwie sieht das nur nach, Getter und Setter sind böse, also nennen wir sie anders, aus.
Genau.
Weder werden Setter durch Umbennennen Tätigkeiten, noch sind Tätigkeiten generell aussagekräftiger oder sonst irgendwie besser. Hier ist sogar das Gegenteil der Fall – ich muss jeweils verschiedene Begriffe verwenden, um ein Attribut zu setzen oder abzufragen. "to move" heisst verschieben/bewegen und nicht Position setzen, also ist das einzig Intuitive, den Position-Verschieber "move" zu nennen und den Position-Setzer "setPosition".
-
Ich benutze get/set (is bei boolean) eigentlich immer, wenn sie es auch wirklich sind. In den meisten Fällen wird ja sowieso effektiv nur ein Wert gesetzt. Vielleicht noch Bound Checks etc, aber grundsätzlich tun getter und setter eigentlich immer das setzen oder holen eines Wertes.
Das macht die Benutzung auch einfacher, weil ich persönlich in externen Bibliotheken auch für das setzen von Werten oder Abfragen von Werten einfach mal zu den getter/settern gehe.
Bei häufig gebrauchten Sachen, wie z.B count oder size mach ich natürlich manchmal eine Ausnahme, weil es dann auch zur Lesbarkeit des Codes beisteuert und durchaus üblicher ist anstatt getCount zu benutzen.