Getter und Setter



  • Hallo,

    ich erlaube mir mal einen neuen Thread für dieses Thema.

    Frage ist auch nicht gebunden an eine Sprache, im konkreten Fall wäre es jetzt Java, aber eigentlich betrifft es alle Sprache, die ähnlich OO sind.

    Als Beispiel, um das Setting kurz zu erklären: Angenommen man soll eine Klasse schreiben, die ein Rechteck in einem kartesischen Koordinatensystem repräsentiert, das zusätzlich auch eine Farbe hat.
    Die Klasse hätte also die Attribute farbe, 2 Seitenlängen und ein Punkt, von dem ausgehend die Seitenlängen addiert werden, um das Rechteck zu formen - sagen wir mal die untere, linke Ecke.

    Jetzt hab ich hier 4 private Attribute und schreibe dann (bzw lasse generieren) für alle 4 getter und setter, oder was?

    Das kommt mit irgendwie so komischvor. Außer in dem Fall, wo ich bei den settern irgendwelche Werte verhindern will, kann ich die Attribute dann auch public machen?

    Ich kenne das mit den ganzen getter / setter aber auch schon aus einer Zeit, wo ich eine Weile an einem Webshop mit Java-Backend mit-entwickelt habe.
    Da war es aber auch der Entwurfsmustern verschuldet - da gab's dann sowas wie Models und DTOs, die nix anderes zu tun hatten, als Daten zusammenzufassen. Da machte es dann auch Sinn, dass man an diese Daten kommt bzw. diese verändern kann.

    Gab dann aber auch sowas wie Controller und Facaden, die hatten tatsächliche Funktion und auch wirklich "private" also interne Attribute, für die man dann auch keine getter / setter hatte.

    --

    Ich nehme also mal an: Die Tatsache, dass ich zu jedem Attribut meiner Klasse sinnvoller Weise getter und setter haben will, ist dem Beispiel verschuldet? Im Endeffekt soll die Klasse ein Rechteck symbolisieren, da ist nicht so viel mit Funktion (zmnd. in dem Beispiel). Irgendwie macht es auch Sinn, dass der User sowas wie Seitenlängen, Farbe und den Ausgangspunkt verändern / auslesen kann.

    D.h. für jedes Attribut getter und setter zu haben wäre in diesem Beispiel durchaus korrekt und sauber?
    Und in der Praxis eigentlich auch üblich, außer die Klassen erfüllen tatsächliche Funktion?

    Solche Snippet-Programmierung bringt mich immer durcheinander. Ich will die Sprache üben und deshalb sauber programmieren, aber oft ist durch die geringe Komplexität vieles ... komisch.



  • Einfachestes Beispiel:

    Die Attribute sind alle public und ich ändere die Kantenlänge.

    Woher weiß deine Grafik-API jetzt dass es das Rechteck neu zeichnen muss?

    Public Attribute bedeutet, dass du jedwege Hoheit über diese Attribute aufgibst. Du weißt nicht wann sie sich auf was ändern. Das kann manchmal OK sein, aber meistens willst du dann doch eine gewisse Kontrolle haben. Sind zB negative Größen für eine Seite ok? Willst du überhaupt verraten wie du den Punkt abspeicherst? Dass es der linke untere ist, ist der Mittelpunkt nicht vielleicht besser, etc? Und das anbieten eines setPosition() dass es eben für Mittelpunkt und Linksunten gibt? Wieso muss der Anwender der Klasse wissen welchen Datentyp du für die Speicherung der Länge verwendest? Was wenn du das nachträglich ändern willst? Was wenn du Transparent als Farbe später mal verbieten willst? etc.

    Public heißt du gibst alle Rechte an den Attribute ab.

    PS:
    Genauso willst du nicht immer getter und setter haben. Denn wie du Sachen intern speicherst sollte dem Anwender egal sein. Wie der Mittelpunkt gespeichert ist, ist egal. Wichtig ist dass der Anwender ein setPosition() machen kann. uU willst du auch die länge einer Seite als Prozent der Maximallänge speichern? Verrate nicht deine geheimen details so leichtfertig. Damit verhinderst du dass du sie später ändern kannst.

    Deshalb gibt man ja auch Enumeration zurückt nicht Vector.



  • Shade Of Mine schrieb:

    Einfachestes Beispiel:

    Die Attribute sind alle public und ich ändere die Kantenlänge.

    Woher weiß deine Grafik-API jetzt dass es das Rechteck neu zeichnen muss?

    Public Attribute bedeutet, dass du jedwege Hoheit über diese Attribute aufgibst. Du weißt nicht wann sie sich auf was ändern. Das kann manchmal OK sein, aber meistens willst du dann doch eine gewisse Kontrolle haben. Sind zB negative Größen für eine Seite ok? Willst du überhaupt verraten wie du den Punkt abspeicherst? Dass es der linke untere ist, ist der Mittelpunkt nicht vielleicht besser, etc? Und das anbieten eines setPosition() dass es eben für Mittelpunkt und Linksunten gibt? Wieso muss der Anwender der Klasse wissen welchen Datentyp du für die Speicherung der Länge verwendest? Was wenn du das nachträglich ändern willst? Was wenn du Transparent als Farbe später mal verbieten willst? etc.

    Public heißt du gibst alle Rechte an den Attribute ab.

    Ja das macht Sinn, ich verstehe. Hatte mich von dem Beispiel verleiten lassen und zu einfach gedacht.
    So wie Du es erklärt hast macht es aber tatsächlich Sinn, für alle 4 Attribute in diesem Beispiel auch Getter/Setter anzubieten.

    Shade Of Mine schrieb:

    PS:
    Genauso willst du nicht immer getter und setter haben. Denn wie du Sachen intern speicherst sollte dem Anwender egal sein. Wie der Mittelpunkt gespeichert ist, ist egal. Wichtig ist dass der Anwender ein setPosition() machen kann. uU willst du auch die länge einer Seite als Prozent der Maximallänge speichern? Verrate nicht deine geheimen details so leichtfertig. Damit verhinderst du dass du sie später ändern kannst.

    Deshalb gibt man ja auch Enumeration zurückt nicht Vector.

    Auch von der Idee hatte ich mich etwas zusehr hinreißen lassen - dass Klassen hauptsächlich interne Attribute haben sollten, mit der sie dann nach außen hin eine gewisse Funktionalität anbieten.

    Aber dafür ist das Beispiel zu wenig komplex, was mich dann im Endeffekt etwas verwirrt hat, weil 50% des Codes getter und setter sind, die auch nix anderes machen als return und =.

    Danke auf jeden Fall für eine Antwort, hat mir sehr weitergeholfen 🙂



  • Ja, gerade bei kleinen Klassen wie zB Point oder Vector3D kann es komisch aussehen mehr Code für getter/setter zu schreiben als für den Rest.

    Deshalb ist immer die Frage: will ich Hoheit über die Attribute behalten. Bei Point2D ist das vielleicht nicht notwendig. Ich habe x und y und das wars. uU reicht es hier x und y public zu machen. Sobald du aber Komplexer wirst, willst du immer die Hoheit behalten.

    Ein wichtiger Punkt ist auch: Achte nie auf die Menge an Code die du schreiben musst um ein Feature zu implementieren. Wenn getter/setter 90% des Codes ausmachen dann ist das halt so. Das sollte aber nie nie nie ein Faktor bei der Entscheidung Pro oder Contra getter/setter sein. Denn Code schreiben und Code Designen sind 2 komplett unterschiedliche Sachen die man nie vermischen sollte.



  • Ich fahre ganz gut mit folgender Faustregel:

    Wenn eine Klasse/Struktur nur dazu dient, Daten zu gruppieren und zu transportieren und also sowas wie ein std::tuple ist packe ich die einzelnen Datenelemente in ein struct und reiche das herum.

    Sobald da etwas Logik dazukommt mache ich eine Klasse draus mit privaten Attributen und schreibe die passenden getter/setter.


Anmelden zum Antworten