Get() und Set()
-
sirchillalot schrieb:
Ich finde man sollte es nicht übertreiben mit Getter und Settern.
[...]
Das Prinzip der Datenkapslung macht imho erst mit einem guten Design Sinn.Das liest sich, als ob du es mit dem guten Design auch nicht übertreiben willst

Vorteil von Gettern und Settern:
- Der Zugriff ist einheitlicher, nämlich immer mit Funktionsklammern und nicht mal mit, mal ohne.
- Du weißt NIE vorher ob du nicht doch irgendwann mal irgendeine Sicherheitsabfrage einbaust oder gar die interne Repräsentation komplett änderst.
Nachteil:
Du musst erstmal die Getter und Setter tippen, obwohl du erstmal nicht absehen kannst, ob du diesen gekapselten zugriff tatsächlich irgendwann brauchst.
-
sirchillalot schrieb:
Ich finde man sollte es nicht übertreiben mit Getter und Settern.
Wenn ich nur einen int Wert habe und für diesen Getter und Setter schreibe, ohne weitere Prüfungen in den Setter/Getter, halte ich es für unsinnig. Dann kann ich den Member auch direkt Public machen.
Eine solche Entscheidung hat mich in einen Projekt Tage der Korrektur eines alten Projektes gekostet (public, static Variablen die etwa wie globale Variablen in jeder Stelle des Projektes wild gesetzt wurden). Und auch nachträglich eine Prüfung einzubauen ist sehr aufwändig.
Wobei ich durchaus dennoch deine erste Aussage akzeptiere, aber in anderen Zusammenhang: Getter/Setter schreibe ich grundsätzlich wenn eine Variable einzeln von außen gelesen/geschrieben werden soll. Public mache ich ausschließlich Werte in kleinen Strukturen die rein zur Übergabe dienen.
-
pumuckl schrieb:
sirchillalot schrieb:
Ich finde man sollte es nicht übertreiben mit Getter und Settern.
[...]
Das Prinzip der Datenkapslung macht imho erst mit einem guten Design Sinn.Das liest sich, als ob du es mit dem guten Design auch nicht übertreiben willst

Vorteil von Gettern und Settern:
- Der Zugriff ist einheitlicher, nämlich immer mit Funktionsklammern und nicht mal mit, mal ohne.
- Du weißt NIE vorher ob du nicht doch irgendwann mal irgendeine Sicherheitsabfrage einbaust oder gar die interne Repräsentation komplett änderst.
Nachteil:
Du musst erstmal die Getter und Setter tippen, obwohl du erstmal nicht absehen kannst, ob du diesen gekapselten zugriff tatsächlich irgendwann brauchst.Ich meine ja nur das man nicht sagen soll Das man immer Getter und Setter verwenden soll. Man sollte sich Gedanken drüber machen wieso man Getter und Setter braucht. Nur einfach weil jemand mal gesagt hat benutz Getter und Setter ist doch sinnlos.
Das mit dem einheitlichen Zugriff ist natürlich auch ein Argument.
-
sirchillalot schrieb:
pumuckl schrieb:
sirchillalot schrieb:
Ich finde man sollte es nicht übertreiben mit Getter und Settern.
[...]
Das Prinzip der Datenkapslung macht imho erst mit einem guten Design Sinn.Das liest sich, als ob du es mit dem guten Design auch nicht übertreiben willst

Vorteil von Gettern und Settern:
- Der Zugriff ist einheitlicher, nämlich immer mit Funktionsklammern und nicht mal mit, mal ohne.
- Du weißt NIE vorher ob du nicht doch irgendwann mal irgendeine Sicherheitsabfrage einbaust oder gar die interne Repräsentation komplett änderst.
Nachteil:
Du musst erstmal die Getter und Setter tippen, obwohl du erstmal nicht absehen kannst, ob du diesen gekapselten zugriff tatsächlich irgendwann brauchst.Ich meine ja nur das man nicht sagen soll Das man immer Getter und Setter verwenden soll. Man sollte sich Gedanken drüber machen wieso man Getter und Setter braucht. Nur einfach weil jemand mal gesagt hat benutz Getter und Setter ist doch sinnlos.
Das mit dem einheitlichen Zugriff ist natürlich auch ein Argument.Das es Zeit kostet Abfragen einzubauen, glaube ich dir. Aber darum sollte man sich im optimalen Fall VORHER Gedanken drüber machen. Dann machen Getter Setter natürlich sehr viel Sinn
-
Da muss man ja sagen, dass die Properties in C# echt sehr, sehr schön sind.
Da stellt sich die Frage gar nicht erst und man kann nix falsch machen.
-
Jockelx schrieb:
Da muss man ja sagen, dass die Properties in C# echt sehr, sehr schön sind.
Da stellt sich die Frage gar nicht erst und man kann nix falsch machen.Das ging mir auch durch den Kopf, aber da hat der Programmierer der Klassen in etwa den gleichen Aufwand. (Ich bin bei C# nicht auf dem aktuellsten Stand kann sein, dass es jetzt auch automatische Versionen gibt).
Das interessante ist ja, dass (ich gehe jetzt davon aus, dass man die Properties selbst noch programmieren muss) man den gleichen Scheibaufwand hat und nur die Benutzung einfacher wird, als mit den Funktionsnamen.
Bei C++ ist die Frage aber meist eher so gestellt, weil man nicht immer get/set Funktionen schreiben will und eher aus Faulheit alles public machen will.Ich persönlich benutze getter und setter eigentlich auch fast immer. Es gibt Ausnahmefälle, wo es wirklich der Lesbarkeit des Codes beiträgt und wirklich nicht notwendig ist, wie z.B bei einer Vektorklasse oder bei einem struct, welches wirklich nur der Datenhaltung dient. Überall sonst gibts eigentlich getter/setter, wenn nötig.
Ich war auch schon froh, dass ich ein einfachesget_x_positionnicht public hatte, sondern bei der Abfrage den Wert noch anpassen konnte. Macht also durchaus Sinn auch einfach scheinende Sachen so zu wrappen. Klar oft braucht mans nicht, aber WENN, dann ist es sehr hilfreich und man muss nicht auch allen Clientcode ändern gehen.
-
Immer Setter und Getter vorziehen. Öffentliche Attribute sind meiner Meinung nach reine Ausnahmen. Schöne Beispiele von öffentlichen Attributen sind zum Beispiel Point, Vector. Aber bereits bei einem Rectangle wird es fragwürdig, ob man da noch öffentliche Attribute verwenden sollte. Meiner Meinung nach nicht.
Lieber ein paar Setter und Getter zuviel, als ein paar zu wenig

Jockelx schrieb:
Da muss man ja sagen, dass die Properties in C# echt sehr, sehr schön sind.
Da stellt sich die Frage gar nicht erst und man kann nix falsch machen.Ehm, naja, Properties in C# sind auch nicht so das Gelbe vom Ei. Schliesslich verstecken sie einfach nur Setter und Getter und lassen die Variable als ein öffentliches Attribute erscheinen, was es aber nicht ist. Sehr schön finde ich zum Beispiel dieses Problem:
public class MyClass { public double MyVar { get; set; } } public class WhatEver { public static void Foo(ref double d) { d = 0.0; } public static void Main(string[] args) { MyClass mc = new MyClass(); Foo(mc.MyVar); // FEHLER, was zur Hölle? ;) } }Properties sehen zwar ganz nett und schön aus, aber es ist halt ein uneinheitlich durchgezogenes Design. Sie sehen aus wie öffentliche Attribute, sind aber tatsächlich Funktionen und können sehr grosse Seiteneffekte auslösen.
Grüssli
-
Ich denke man solte sich vorher Gedanken machen was man wann und wo nutzt. Wenn Klassen Variablen enthalten die nicht geändert werden dürfen oder eine Sicherheitsabfrage beim setzen brauchen kommen nur get/set in der Klasse vor. Bei Klassen wo es jedoch erdacht ist das man die Variablen oft ändern, wie zB Vectoren, sind sie bei mir öffentlich. Je nach Bedarf aber einheitlich inenrhalbd er Klasse, willde Mixes aus öffentlichen Variablen und get/set innerhalb eienr Klasse finde ich nicht schön.
-
in etwa den gleichen Aufwand. (Ich bin bei C# nicht auf dem aktuellsten Stand kann sein
Seit 3.0 geht das ganz fix mit
public int bla {get; set;}Dravere schrieb:
Ehm, naja, Properties in C# sind auch nicht so das Gelbe vom Ei. Schliesslich verstecken sie einfach nur Setter und Getter und lassen die Variable als ein öffentliches Attribute erscheinen, was es aber nicht ist.
Das ist dann aber irgendwo dein Problem, dass du das extra falsch interpretierst.
Interpretierst du die Properties als kurz geschriebene (s.o.), besser zu lesen (zalh = 5 statt zahl.setZahl(5)) Getter/Setter, dann sind die schon schön.
-
@Xebov
Das Problem an dem Vorgehen ist halt, dass man nie weiss, was noch alles geändert werden wird. Und wenn du dann nur wegen get/set jedem Client, der deinen Code benutzt sagen musst, dass sie den umschreiben müssen ist das richtig doof.
Vor allem kann alles, mag es auch noch so unaugescheinlich sein irgendwann eine kompliziertere Abfrage des Wertes erfordern.Als Beispiel, was bei mir mal vorkam. Ich habe eben eine solche get_x_position gehabt. Denkt man, dass man da einfach (z.B von einem Fenster) die x_position offen legt und dann kann man abfragen und setzen. Ich habe das nicht so gemacht und war richtig froh, als ich auf die Idee kam verschiedene Variationen von get_x_position zu machen. Man konnte dann die x_position relativ zu einem Parentfenster haben, oder des selben oder aber auch von der rechten, anstatt von der linken Seite aus gerechnet. Macht also auch da Sinn. Und im zuge von Erweiterungen kommt das denke ich sehr oft auch für einfache Variablen vor.
Wie gesagt bei einer Vektor oder Point Klasse ist es schon sinnvoll, aber das ist wirklich die Ausnahme, aber auch nur, weil die Funktionsweise sehr definiert ist und wenn es sich anderst verhalten würde sehr unintuitiv für einen Benutzer wäre. Die meisten Klassen sind aber nicht so streng definiert, wie eine Vektor Klasse und wie Dravere sagt macht es bereits bei einer Rechteck Klasse schon nicht mehr unbedingt soo viel Sinn.
@Jockelx
Ok, war ja mal, dass man die Zuweisung noch explizit hinschreiben musste.
Der Punkt ist aber, dass Schreibarbeit kein Argument für oder gegen Getter/Sett sein dürfen (wie auch sonst nirgends bei einer Designentscheidung).
-
drakon schrieb:
Wie gesagt bei einer Vektor oder Point Klasse ist es schon sinnvoll, aber das ist wirklich die Ausnahme, aber auch nur, weil die Funktionsweise sehr definiert ist und wenn es sich anderst verhalten würde sehr unintuitiv für einen Benutzer wäre. Die meisten Klassen sind aber nicht so streng definiert, wie eine Vektor Klasse und wie Dravere sagt macht es bereits bei einer Rechteck Klasse schon nicht mehr unbedingt soo viel Sinn.
Deswegen sagte ich ja auch man soll sich vorher genau Gedanken machen für was die Klasse vorgesehen ist. Das set und get in den meisten Fällen Sinn machen da stimm ich dir voll und ganz zu, allein schon weil man oft genug Variablen vor Änderungen schützen muß.
-
drakon schrieb:
Der Punkt ist aber, dass Schreibarbeit kein Argument für oder gegen Getter/Sett sein dürfen (wie auch sonst nirgends bei einer Designentscheidung).
Das wird zwar jetzt leider alles etwas OT, aber sei's drum:
Hier (bzw. bei dem was ich sagte) geht es nicht um Design des Programmierers, sondern um das gute Design der Sprache C# und da ist mir Schreibarbeit schon wichtig.
Den C#-Leuten übrigens auch, sonst hätten sie die Kurzschreibweise nicht eingeführt.
-
Jockelx schrieb:
drakon schrieb:
Der Punkt ist aber, dass Schreibarbeit kein Argument für oder gegen Getter/Sett sein dürfen (wie auch sonst nirgends bei einer Designentscheidung).
Das wird zwar jetzt leider alles etwas OT, aber sei's drum:
Hier (bzw. bei dem was ich sagte) geht es nicht um Design des Programmierers, sondern um das gute Design der Sprache C# und da ist mir Schreibarbeit schon wichtig.
Den C#-Leuten übrigens auch, sonst hätten sie die Kurzschreibweise nicht eingeführt.Absolut.
Ich wäre auch für eine bessere Variante in C++, aber da es sie nicht gibt sollte man nicht das Design drunter leiden lassen und Code unwartbar draus werden lassen.
-
Jockelx schrieb:
Das ist dann aber irgendwo dein Problem, dass du das extra falsch interpretierst.
Interpretierst du die Properties als kurz geschriebene (s.o.), besser zu lesen (zalh = 5 statt zahl.setZahl(5)) Getter/Setter, dann sind die schon schön.Liest du auch, was ich schreibe?
Dravere schrieb:
Properties sehen zwar ganz nett und schön aus, aber es ist halt ein uneinheitlich durchgezogenes Design. Sie sehen aus wie öffentliche Attribute, sind aber tatsächlich Funktionen und können sehr grosse Seiteneffekte auslösen.
Ich sage nicht, dass sie nicht schön sind, ich sage es ist ein uneinheitliches Design und daher widerspreche ich dir in folgendem Punkt völlig:
Jockelx schrieb:
... sondern um das gute Design der Sprache C# ...
Frage an dich. Da es ja anscheinend nur an meiner falschen Interpretation liegt, kannst du die beiden folgenden Anweisungen ohne Probleme unterscheiden, ob es jeweils ein Property oder öffentliches Attribute ist:
MyClass myObject = new MyClass(); myObject.X = 30; // ist myObject.X ein Property oder nicht? myObject.D = 30; // ist myObject.D ein Property oder nicht?X kann ein Property sein, während D ein öffentliches Attribute ist. Nun findet bei myObject.X ein Funktionsaufruf statt, bei myObject.D findet kein Funktionsaufruf statt, obwohl beides genau gleich geschrieben wird. Gleiche Schreibeweise, unterschiedliches Verhalten, sowas nenn ich ein extrem schlechtes Design. Daher liegt es auch nicht an meiner Interpretation, man kann sie nicht unterscheiden, wenn man nicht die Klasse sieht. Und ein öffentliches Attribute oder eine Funktion sind zwei sehr unterschiedliche Dinge.
Klar, es sieht schöner aus, aber das Design an sich ist schrecklich. Da hätte man besser eine andere Syntax einführen sollen. Wäre vieles möglich gewesen, zum Beispiel:
myObject.X = 30; // Öffentliches Attribute myObject{D} = 30; // PropertyOder sonst irgendwas. Diese fehlende Unterscheidung macht es meiner Meinung nach zu einem schlechten Design.
Also zusammengefasst:
Die Idee ist gut, die Umsetzung ist schlecht.Grüssli
-
Dravere schrieb:
kannst du die beiden folgenden Anweisungen ohne Probleme unterscheiden, ob es jeweils ein Property oder öffentliches Attribute ist:
Von wem ist die Klasse?
Von Microsoft oder sonst jemandem der das Konzept der Properties nicht extra aushebelt?
Dann ja, kann ich: Ist ein Property.
-
Dravere, das sehe ich nicht so (und auch der Großteil der C#-Gemeinde nicht).
In C# sollten generell alle Member privat sein und nur durch Properties nach außen gereicht werden (wenn überhaupt).
Leider gab es vor C# 3.0 noch nicht die bequeme Abkürzung für die Properties, so daß aus Bequemlichkeit leider noch public Member in vielen Source-Code existieren (wobei das VS schon immer die Refaktoring-Möglichkeit 'Encapsulate Field' angeboten hat). Das .NET-Framework verwendet aber durchgehend Properties - einzige Ausnahme sind 'static readonly member'.
-
@Jockelx, Th69,
Auch wenn man es umgehen kann, durch das eigene Programmdesign, das Design der Sprache bleibt gleich und somit schlecht. Wie ich schon sagte, die Idee finde ich extrem toll, die Umsetzung aber nicht. Und weil die Umsetzung schlecht ist, muss man eben sein eigenes Design so anspassen, um dem entgegen zu wirken. Ihr bestätigt grundsätzlich nur meine Aussage, wenn ihr sagt, dass man halt keine öffentlichen Attribute verwenden darf. Wieso gibt es dann überhaupt öffentliche Attribute? Es existiert hier eben eine Inkonsistenz. Es ist nicht ganz sauber durchgezogen.Grüssli
-
Eiffel umschifft das ganze recht elegant.

1. Gibt es keine unterschiedliche Notation für den Aufruf einer Funktion ohne Argumente und einer Datenmember. Datenmember können also public sein und man kann bei Bedarf noch eine Funktion drunter hängen.
2. Die Datenmember sind standardmässig readonly. Das heisst man muss einen setter angeben (mit assign), welcher zum zuweisen benutzt wird.
3. Ob ein Objekt per Value oder per Referenz rumgereicht wird entscheidet nicht der Benutzer der Klasse, sondern der Programmierer der Klasse. (üblicherweise ist es per Referenz, ausser bei so Sachen, wie INTEGER, FLOAT usw.)
class FOO feature n: INTEGER assign set_n -- datenmember + angabe des setters bar : INTEGER -- funktion do Result := n end set_n ( n_ : INTEGER ) do n := n_ end endDer Zugriff erfolg genau gleich:
class BAR feature bar local f: FOO do f.create f.n f.bar -- kein Unterschied f.n := 2000 -- der setter wird benutzt end endDas finde ich wirklich cool.
Sorry für OT, aber da wir eh schon bei C++/C# sind dachte ich, dass ich mal noch eine Alternative reinwerfe, welche imo C# überlegen ist.
(natürlich ist mir klar, dass Eiffel für solche Sachen ein Einschränkungen macht, aber das sei aussen vor gelassen. Rein der Mechanismus und Umgehung der Probleme ist richtig gut)
-
Und darum z.B. mag ich Java nicht so sehr, weil man dort immer getX() und setX() verwenden muß.
In C++ verwende ich für Properties eine template-basierte Lösung...
P.S. Sorry dravere, aber die Frage finde ich sehr eigenartig - genauso argumentieren ja viele Leute mit C++: warum kann man dies und das machen, obwohl das nur Probleme mit sich bringt? Und C# ist viel regelbasierter designt. Und gerade die einfache Umstellung einer öffentlichen Membervariablen auf ein Property ändert eben nicht die Syntax beim Aufruf (einzig bei Reflection hat dies entsprechende Nachteile). Du siehst, was du als schlechtes Design ansiehst, finde ich (und wohl auch die C#-Designer) dagegen super.
(nicht noch eine Syntax mehr - alleine LINQ und Lambda-Expression sind für viele Anfänger eine große Hürde -)
-
Jockelx schrieb:
Das wird zwar jetzt leider alles etwas OT, aber sei's drum:
Hier (bzw. bei dem was ich sagte) geht es nicht um Design des Programmierers, sondern um das gute Design der Sprache C# und da ist mir Schreibarbeit schon wichtig.
Den C#-Leuten übrigens auch, sonst hätten sie die Kurzschreibweise nicht eingeführt.Den C++-Leuten offenbar nicht, sonst würden sie Makros für Getter- und Setterfunktionen, deren Implementierung in 95% der Fälle gleich aussieht, verwenden.
Dravere schrieb:
Gleiche Schreibeweise, unterschiedliches Verhalten, sowas nenn ich ein extrem schlechtes Design.
Andere hingegen sprechen von Polymorphie.

Th69 schrieb:
Und darum z.B. mag ich Java nicht so sehr, weil man dort immer getX() und setX() verwenden muß.
Muss man ja gar nicht, dort gibts schliesslich auch
public. Allerdings kommt mir die Java-Mentalität grundsätzlich etwas so vor, dass OOP teilweise überbewertet und für Dinge eingesetzt wird, für die man in Sprachen wie C++ andere Konzepte hat (jetzt nicht speziell auf Get/Set bezogen). Von daher wäre ein Java-Programmierer möglicherweise noch stärker abgeneigt gegenüber ungekapselten Klassen.