Folgen Sie dem Video unten, um zu sehen, wie Sie unsere Website als Icon auf Ihrem Homescreen erstellen.
Anmerkung: This feature may not be available in some browsers.
Nochmal: Mich interessiert der innere Zustand nicht. Deswegen Getter. Damit bekomme ich Informationen aus dem Objekt raus, ohne den internen Zustand kennen zu müssen. Beispiel:
Es wäre nicht Aufgabe der Mailklasse den vollständigen Namen des Benutzers zusammenzustückeln.Code:class Benutzer { public string VollständigerName() { if(spitzname) return name + " '" + spitzname + "' " + nachname; return name + " " + nachname; } }
Was ist dein
denn anderes als ein Setter?Code:void einschreiben(Student student) raises EinschreibenFehlgeschlagenException;
Willst du etwa dass die Vorlesung für sämtliche Aktionen zuständig ist, die mit der Liste der Studenten möglich ist? Also drucken, als HTML ausgeben, als PDF ausgeben, per Mail an den Dozenten verschicken? Dann muss man für jede neue Aktion das Objekt verändern. *DAS* ist schlechtes Design. Da landen wir beim gleichen Problem wie beim Benutzer-Objekt. Willst du jetzt die Vorlesung auch zu einer Entität degradieren und die Logik wieder an eine anderes Klasse delegieren? Da dreht man sich nur wieder aufs neue im Kreis.
Wenn du den Zustand eines Objektes von außen nicht manipulieren willst, dann darf keine einzige Methode deiner Klasse Parameter erwarten, denn jede könnte den Zustand deines Objektes ändern.
Ich verstehe dich da nicht, es geht fast immer da drum den internen Zustand eines Objektes zu manipulieren. Wie willst du zu einer Liste ein neues Objekt hinzufügen wenn du den Zustand nicht verändern darfst?
Edit: Irgendwie hab ich das Gefühl wir meinen verschiedene Sachen, aber ich habe nicht die geringste Vorstellung was du meinst.
void setFoo(Foo foo) {
this.foo = foo;
}
Ich weiß nicht, was du mir damit jetzt sagen willst. Ich habe nicht behauptet, dass das Benutzer-Objekt dem Email-Objekt die Adresse zusammenbasteln soll.War mir klar, dass das Beispiel kommt Natürlich möchtest du der Email-Klasse überlassen, wie sie Email-Adressen formuliert! Dem User ist absolut egal, wie das legitime Format einer vollständigen Emailadresse ist. Das interessiert nur das Objekt, das die Email versendet.
Nichts anders ist ein Setter!Das ist irgendwas! Klar füge ich dem Objekt den Nutzer zu. "einschreiben" ist aber eine Methode der Funktion mit einem Parameter und nicht ein Manipulator eines Objektfeldes.
Und genau das extrem schlechtes Design. Da versteigst du dich in Helfer-Klassen und zusätzlichen Methoden obwohl du eigentlich nur eine Funktion brauchst die dir eine Liste der Studenten zeichnet.Dann gibt es ein Objekt, das HTML erzeugt. Es ist ein "Helper"-Objekt der Klasse Vorlesung. Dieser sagst du dann "vorlesung.print_students_as_html()" oder "vorlesung.print_students_as_pdf()". Irgendwo muss ich das ja ändern, wenn ich neue Funktionen hinzufügen möchte. Das Vorlesungs-Objekt bekommt also eine neue Methode und zusätzlich, wenn man die Funktionalität kapseln möchte, eine private Helper-klasse.
class Vorlesung {
private List<Student> studenten;
List<Student> ListeDerStudenten() {
return studenten.copy();
}
}
Genau das tun Setter. Setter verändern kontrolliert den Zustand eines Objektes. Unkontrolliert wäre eine öffentliche Eigenschaft.Nein, das habe ich nicht gesagt! Setter setzen ein Feld des Objektes! Ich habe nicht gesagt, dass es keinen eingehenden Datenverkehr geben darf! Es darf nur nicht unkontrolliert von außen auf Felder zugegriffen werden. Eine Methode mit Parametern erfüllt eine bestimmte Funktion auf Basis von seinem eigenen State und den Parametern.
Ich weiß nicht, was du mir damit jetzt sagen willst. Ich habe nicht behauptet, dass das Benutzer-Objekt dem Email-Objekt die Adresse zusammenbasteln soll.
Nichts anders ist ein Setter!
Dann gibt es ein Objekt, das HTML erzeugt. Es ist ein "Helper"-Objekt der Klasse Vorlesung. Dieser sagst du dann "vorlesung.print_students_as_html()" oder "vorlesung.print_students_as_pdf()". Irgendwo muss ich das ja ändern, wenn ich neue Funktionen hinzufügen möchte. Das Vorlesungs-Objekt bekommt also eine neue Methode und zusätzlich, wenn man die Funktionalität kapseln möchte, eine private Helper-klasse.Und genau das extrem schlechtes Design. Da versteigst du dich in Helfer-Klassen und zusätzlichen Methoden obwohl du eigentlich nur eine Funktion brauchst die dir eine Vorlesung Zeichnet. Gutes Design wäre:
Code:class Vorlesung { private List<Student> studenten; List<Student> GetStudentenListe() { return studenten.copy(); } }
Genau das tun Setter. Setter verändern kontrolliert den Zustand eines Objektes. Unkontrolliert wäre eine öffentliche Eigenschaft.
Oh Contrair! Was für Kontrolle?
Ein sauberes Design wäre:
Code:class Vorlesung { private List<Student> studenten; void printList(IVLPrinter printer) { return printer.print(this.studenten); } boolean is_contender(Student student) { return studenten.contains(student); } ... }
Auf diese Art und Weise erlaube ich nur dem Printer den Zugriff auf die Liste der Studenten, niemanden sonst. Gebe ich ihm noch eine Immutable List oder eine Deep-Copy der Liste, kann ich auch sicher sein, dass nicht ein IVLPrinter injiziert wird, der doch mal an der Liste herumspielt
Ja. Etwas übertrieben vielleicht, aber das ist Ansichtssache und kommt auf den Einzelfall an.Ein sauberes Design wäre:
Code:class Vorlesung { private List<Student> studenten; void printList(IVLPrinter printer) { return printer.print(this.studenten); }
Da stimme ich ohne Einschränkung zu.Code:boolean is_contender(Student student) { return studenten.contains(student); } ... }
War immutable nicht vorhin noch schlechtes Design? Wie gesagt, das selbe erreichst du mit einem GetStutendList auch.Gebe ich ihm noch eine Immutable List oder eine Deep-Copy der Liste
Offensichtlich. Das Problem das ich sehe, ist, dass es von außen einfach nicht erkennbar ist, ob ein Setter ein „echter“ Setter ist oder nicht. Das kann mal der Fall gewesen sein. Aber evtl. ist seit Einführung des Setters das Feld für das er mal zuständig war nicht mehr existiert. Ist es deswegen kein Setter mehr? Und woran sollte man das von außen erkennen?Wir haben ein unterschiedliches Verständnis von Settern.
Ja. Etwas übertrieben vielleicht, aber das ist Ansichtssache und kommt auf den Einzelfall an.
Da stimme ich ohne Einschränkung zu.
Offensichtlich. Das Problem das ich sehe, ist, dass es von außen einfach nicht erkennbar ist, ob ein Setter ein „echter“ Setter ist oder nicht. Das kann mal der Fall gewesen sein. Aber evtl. ist seit Einführung des Setters das Feld für das er mal zuständig war nicht mehr existiert. Ist es deswegen kein Setter mehr? Und woran sollte man das von außen erkennen?
War immutable nicht vorhin noch schlechtes Design? Wie gesagt, das selbe erreichst du mit einem GetStutendList auch.
Da kann man bei Java sowieso nicht von sprechen.Ja schlechtes Design bei Gettern *grins*
Ja und? Ist alles nur eine Frage inwieweit man das Design unnötig verkompliziert.Erreichst du das wirklich? Mit dem Getter darf jeder, der sich im Namespace befindet, die Liste erhalten. In meinem Design darf das nur der Printer!
Ja und? Ist alles nur eine Frage inwieweit man das Design unnötig verkompliziert.
Weil du für jede neue Aktion ein neues Interface brauchst. Wenn du die Studentenliste nach allen Studenten mit Anfangsbuchstabe "A" suchen willst brauchst du entweder ein neues Interface, missbrauchst eine Printer-Klasse oder nimmst einfach die Kopie der Studentenliste die dir schon zur Verfügung steht.Was verkompliziert da?
Wayne? Wenn das wirklich so kritisch ist gibt es eben keinen Getter. Aber das jemand das Printer-Interface mißbraucht kann das auch nicht verhindern.Das sorgt nur dafür, dass wirklich nur der mit den Daten operiert, der sich dafür interessieren darf!
Weil du für jede neue Aktion ein neues Interface brauchst. Wenn du die Studentenliste nach allen Studenten mit Anfangsbuchstabe "A" suchen willst brauchst du entweder ein neues Interface, missbrauchst eine Printer-Klasse oder nimmst einfach die Kopie der Studentenliste die dir schon zur Verfügung steht.
Aus dem selben Grund aus dem ich die Liste drucken will. Wenn keine Informationen aus den Klassen nach außen dringen dürfen, kann ich gleich aufhören zu Programmieren.Warum willst du von außen nach der Liste aller Studenten mit dem Anfangsbuchstaben 'A' suchen? Das ist genauso sinnvoll wie ein Getter.
Weil?Du wirst die Printerklasse nicht missbrauchen (das ist übrigens ein Interface, welches von verschiedenen Printern implementiert werden kann).
Weil du für jede neue Aktion ein neues Interface brauchst. Wenn du die Studentenliste nach allen Studenten mit Anfangsbuchstabe "A" suchen willst brauchst du entweder ein neues Interface, missbrauchst eine Printer-Klasse oder nimmst einfach die Kopie der Studentenliste die dir schon zur Verfügung steht.
Wayne? Wenn das wirklich so kritisch ist gibt es eben keinen Getter. Aber das jemand das Printer-Interface mißbraucht kann das auch nicht verhindern.
Aus dem selben Grund aus dem ich die Liste drucken will. Wenn keine Informationen aus den Klassen nach außen dringen dürfen, kann ich gleich aufhören zu Programmieren.
Der selbe Satz hätte von mir stammen können.Du übertreibst maßlos oder willst mich mit Absicht nicht verstehen.
Der selbe Satz hätte von mir stammen können.
Ich glaube wir können die Diskussion hier abbrechen, das führt zu nichts.
was meinste du denn mit noch mehr setzen? wie setzt du denn das feld sonst, mit einer methode vom objekt?Ich bin strikter Verfechter des Grundsatzes, dass Getter evil sind und Setter faktisch unnötig, und das in jeder Sprache!. Warum? Wenn ich ein Feld an einem Objekt setzen will, setze ich das Feld. Wenn ich beim Setzen noch mehr mache, als das Feld zu setzen, ist es kein Setter mehr, ergo: unnötig.
du wuerdest also dem objekt eine methode schreiben, um sich selbst anzuzeigen? also anstatt einem getName eine methode print die einfach den namen anzeigt?Getter wiederum zeigen, dass ich außerhalb des Objektes ein Implementierungsdetail benötige. Das zeigt mir aber, dass mein Design schlecht ist. Was interessiert mich außerhalb eines Objektes ein bestimmtes Feld, dass dort verwendung findet? Besser ist es doch, den die gewünschte Arbeit machen zu lassen, der davon ahnung hat, in diesem Fall das Objekt mit dem Feld, anstatt es außerhalb zu manipulieren.
Das fällt einem spätestens dann auf die Füße, wenn die Implementierung des Objektes mit dem Feld nicht von einer Manipulation von Außen ausgeht. ("Der Getter sollte ja nur den Status zurückgeben, ein Programmierer verändert aber jetzt das Feld -> call by reference -> das Objekt verändert sich") Und dann knallt es weil es zu Seiteneffekten kommt.