# Design ohne Getter und Setter



## deamon (29. Apr 2009)

Hallo,

ich habe den Artikel Why getter and setter methods are evil gelesen und kann nachvollziehen, dass es schlechte Praxis ist, intern verwendete Datentypen über get- und set-Methoden zugänglich zu machen. Der Autor argumentiert, dass dieses Muster nur für die Werkzeugunterstützung eingeführt, damit man etwa beim Zusammenklicken einer GUI gleich sieht, an welchen Parametern man drehen kann.

Der Autor bringt ein Beispiel, wo man statt "String getId()" lieber eine Methode implementieren soll, die das tut, was man sonst außerhalb mit dem Feld "login" tun würde, beispielsweise "drawYourself()", das die Darstellung übernimmt. Damit ist anderer Code nicht davon abhängig, dass die ID ein String ist, es könnte auch ein Foto oder sonstwas sein. Nun merkt er aber selbst an, dass er damit GUI-Code in sein Domänenmodell bringt, bestreitet aber sogleich, dass er das tatsächlich tut, weil die eigentliche Darstellung ja mit AWT oder Swing außerhalb stattfinden würde. Er schreibt, dass der das Problem mit möglicherweise wechselnden GUIs dadurch lösen könnte, dass er eine "give-me-a-JComponent-that-represents-your-identity class" einführt. Bloß damit wäre die eigentliche Klasse ja immer noch von z. B. Swing abhängig, was ich nicht besonders schön finde.

Wenn ich an verschiedene Frameworks wie Spring MVC oder Wicket denke, fällt mir kaum ein sinnvoller weg ein, wie man die Darstellung der Klasse überlassen sollte. In Wicket würde man wohl eine Wicket-Komponente zurückegeben. Aber in Spring MVC könnte man keine GUI-Komponente zurückgeben, man müsste wohl HTML erzeugen. Aber selbst wenn man das täte, bliebe das Problem, wie die Werte aus einem Formular dann zurück in das Objekt kommen?

Bei dem klassischen Fall mit Gettern und Settern, werden z. B. in Wicket die Zugriffsmethoden der jeweiligen Felder aufgerufen, um die Formularwerte zu übernehmen. Wie sollte das ohne Getter und Setter laufen?

```
public class Person {

	private String nachname, vorname, email, strasse, plz, ort;
	
	public String getNachname() {return nachname;}
	public void setNachname(String nachname) {this.nachname = nachname}
	// usw ...
	
}
```

Der Autor bringt noch Reflection und die Annotation @Property (gibt es die offiziell?) ins Spiel. D.h. man könnte alle Felder "private" machen und wenn ein Formular abgesendet wird, die Daten per Reflection direkt in die Felder schreiben. Bloß das ändert an dem Problem ja nichts. Wenn ein Feld ein boolean ist, muss aus dem Formular auch ein boolean kommen. Und wenn das boolean-Feld irgendwann in eine Enumeration umgewandelt wird, muss man die Stelle wo der Wert gesetzt wird, genauso ändern, wie man es mit einem Setter tun müsste.

Wie würde man das in SmallTalk machen? Ich habe gelesen, da bräucht men sowas wie Getter und Setter dank des Nachrichtenkonzepts nicht. Hier ist ein Beispiel in Ruby, aber beantwortet nicht die Frage, wie Werte gesetzt werden:
http://www.java-forum.org/allgemeine-java-themen/47023-getter-und-setter.html

So reizvoll ich die Idee finde, ohne Getter und Setter zu programmieren, mir fällt kein vernünftiger Weg ein, das tatsächlich zu tun. Seht ihr einen Weg?


----------



## maki (29. Apr 2009)

Das Problem ist kei GUI spezifisches sondern ein allgemeines.

Ganz ohne Getter und Setter ist ja auch übertrieben.
Das eigentliche Problem wenn man nur "dumme" POJOs einsetzt ohne echte Logik aber dafür mit Gettern&Settern für alle Felder ist ein grundlegendes mit der OO: Encapsulation & Information hiding
Ersteres wird durch Getter & Setter erfüllt, letzteres wird gebrochen wenn man einfach alle internas per getter & setter zugänglich macht.
Anstatt einfach für alles Getter&Settern zu erstellen kann man sich ja vernünftige Schnittstellen überlegen, inkl. Delegation etc.

Sog. "trainwrecks", also zugriffe tief in den Objektgraphen hinein (object1.getObject2().getObject3().getObject4().doSomething) sind kein gutes Design, denn hier gibt es kein Information Hiding und der aufrufer muss die internas von object1, object2, object3  und object4 kennen und ist natürlich abhängig von diesen, jede Änderung wirkt sich auf den Clientcode aus.
Das sog. Law of Demeter wird gebrochen: Law of Demeter - Wikipedia, the free encyclopedia


----------



## tfa (29. Apr 2009)

Verteufeln würde ich Getter und Setter nicht, man muss sie vernünftig einsetzen. 
Ich kann mich erinnern, diesen Holub-Artikel mal vor Jahren gelesen zu haben. In den Kommentaren wurde seine Thesen kontrovers diskutiert, um nicht zu sagen runter gemacht. Leider scheinen die Kommentare irgendwann gelöscht worden zu sein. Das was da jetzt steht, ist jedenfalls fast 6 Jahre älter als der Artikel. Schade.



> Wie würde man das in SmallTalk machen? Ich habe gelesen, da bräucht men sowas wie Getter und Setter dank des Nachrichtenkonzepts nicht. Hier ist ein Beispiel in Ruby, aber beantwortet nicht die Frage, wie Werte gesetzt werden:


In Smalltalk ist alles Public, da braucht man keine Accessoren.
Ruby bietet so tolle Sachen wie Mix-Ins, womit man seine Klassen und Objekte im Bedarfsfall erweitern kann. Je nachdem was man braucht, importiert man sich dann eben Methoden zur Anzeige unter Swing oder AWT oder SWT etc. Das ist ein ziemlich mächtoges Konzept, was sich in statischen Sprachen wie Java so nicht umsetzten lässt.


----------



## deamon (29. Apr 2009)

tfa hat gesagt.:


> In Smalltalk ist alles Public, da braucht man keine Accessoren.



Aber wie funktioniert der Zugriff auf diese öffentlichen Felder? Wenn ich in SmallTalk eine Klasse "Person" mit Vor- und Nachname usw. habe und diese Werte von außen direkt zugänglich sind, habe ich doch das gleiche Problem, wie in Java wenn man alles public macht, oder nicht?



tfa hat gesagt.:


> Ruby bietet so tolle Sachen wie Mix-Ins, womit man seine Klassen und Objekte im Bedarfsfall erweitern kann. Je nachdem was man braucht, importiert man sich dann eben Methoden zur Anzeige unter Swing oder AWT oder SWT etc. Das ist ein ziemlich mächtoges Konzept, was sich in statischen Sprachen wie Java so nicht umsetzten lässt.



Mixins gibt es in Java zwar nicht, aber man könnte etwas Vergleichbares relativ leicht mit dem Strategiemuster umsetzen. Aber das ist wieder ein neues Thema, was nichts mehr mit Gettern und Settern zu tun hat ...


----------



## maki (29. Apr 2009)

Mix-ins gibt es in Java, aber wohl nicht wie in Ruby.

Dazu reicht es das ein Objekt mehrere Interfaces implementiert: Mixin - Wikipedia, the free encyclopedia


----------



## tfa (29. Apr 2009)

Nein, das ist weit davon entfernt, was Ruby (oder auch andere Sprachen) unter Mix-Ins verstehen. In Java kann man das höchstens umständlich simulieren, z.B. mit AOP.


----------



## byte (29. Apr 2009)

[DUKE]Bytecode Instrumentation ftw [/DUKE]


----------



## faetzminator (29. Apr 2009)

Ich verstehe nicht, warum man auf Getters und Setters verzichten will. In diesen Methoden müssen manchmal auch Validierungen gemacht oder andere Felder oder was auch immer updated werden. Was macht man, wenn man in einer neuen Programmversion plötzlich etwas zusätzliches aufrufen will, aber eine public Variable hat? Diese auf @deprecated setzen und dann Getter und Setter implementieren? Macht IMHO keinen Sinn.


----------



## maki (29. Apr 2009)

faetzminator hat gesagt.:


> Ich verstehe nicht, warum man auf Getters und Setters verzichten will. In diesen Methoden müssen manchmal auch Validierungen gemacht oder andere Felder oder was auch immer updated werden. Was macht man, wenn man in einer neuen Programmversion plötzlich etwas zusätzliches aufrufen will, aber eine public Variable hat? Diese auf @deprecated setzen und dann Getter und Setter implementieren? Macht IMHO keinen Sinn.


Es geht nicht darum alle Getter & Setter durch public Felder zu ersetzen, sondern viele Getter&Setter durch besseres Design


----------

