JavaRush /Java-Blog /Random-DE /Getter/Setter. Teuflisch. Und Punkt
angelina
Level 5

Getter/Setter. Teuflisch. Und Punkt

Veröffentlicht in der Gruppe Random-DE
Artikel von Egor Bugaenko 19. September 2014 | Gepostet in: Core Java Getter/Setter.  Teuflisch.  Und Punkt - 1 Diese alte Debatte wurde von Allen Holub im Jahr 2003 in seinem berühmten Artikel „ Warum Getter- und Setter-Methoden böse sind – Sind Getter/Setter ein Anti-Muster und sollten wir sie vermeiden, oder ist es etwas, was wir tun?“ angestoßen. müssen Sie unbedingt haben? in der objektorientierten Programmierung benötigt. Ich werde meinen Beitrag zu dieser Diskussion leisten. Der Kern des folgenden Textes lautet: Getter und Setter sind eine schlechte Praxis; diejenigen, die sie verwenden, haben keine Entschuldigung. Aber um Missverständnissen vorzubeugen, schlage ich keineswegs vor, dass die Verwendung von get/set nach Möglichkeit vermieden werden sollte. Nein. Ich sage, dass Sie sie nicht einmal in die Nähe Ihres Codes gelassen haben . Getter/Setter.  Teuflisch.  Und Punkt - 2Was halten Sie von dieser Aussage? Verdient es Ihre Aufmerksamkeit? Verwenden Sie das Get/Set-Muster seit 15 Jahren und sind Sie ein angesehener Java-Architekt? Und Sie wollen sich diesen Unsinn gar nicht erst von einem Fremden anhören? Nun... ich verstehe deine Gefühle. Mir ging es genauso, bis ich auf David Wests Buch „Object Thinking“ stieß – es ist das beste Buch über objektorientierte Programmierung, das ich je gelesen habe. Also bitte. Beruhigen Sie sich und versuchen Sie zu verstehen, was ich erklären möchte. Gegenstand der Kontroverse Es gibt mehrere Argumente gegen „Accessoren“ (ein anderer Name für Getter und Setter) in der objektorientierten Welt. Und es sind alles sehr richtige Argumente. Werfen wir einen kurzen Blick darauf. Fragen, nicht erzählen : Allen Holub sagt: „Fragen Sie nicht nach Informationen, die Sie für die Erledigung einer Aufgabe benötigen; ‚bitten‘ Sie das Unternehmen, das über diese Informationen verfügt, die Aufgabe für Sie zu erledigen.“ Prinzip der verletzten Kapselung : Ein Objekt kann von anderen Objekten zerlegt werden, da diese über Setter beliebige Daten in das Objekt einbetten können. Ein Objekt kann seinen eigenen Zustand einfach nicht sicher genug kapseln, da jeder diesen Zustand ändern kann. Offengelegte Implementierungsdetails : Wenn Sie ein Objekt von einem anderen Objekt erhalten können, verlassen wir uns zu sehr auf die Implementierungsdetails des ersten Objekts. Wenn es sich morgen ändert (z. B. der Ergebnistyp), müssen wir den Code ändern. Alle oben genannten Begründungen sind sicherlich sinnvoll, aber hier geht der wichtigste Punkt außer Acht. Grundlegendes Missverständnis Die meisten Programmierer glauben, dass ein Objekt eine Datenstruktur mit Methoden ist. Ich zitiere den Artikel von Bozhidar Bozhanov: Getter und Setter sind nicht böse. Die meisten Objekte, für die Getter und Setter erstellt werden, enthalten jedoch lediglich Daten. Dieses Missverständnis ist das Ergebnis eines großen Missverständnisses! Objekte speichern nicht „nur Daten“. Objekte sind keine Datenstrukturen mit angehängten Methoden. Dieses Konzept der „Datenspeicherung“ stammt aus objektorientierten Programmier- und Verfahrenssprachen, insbesondere C und COBOL. Ich wiederhole es noch einmal: Ein Objekt ist nicht nur eine Sammlung von Datenelementen und Funktionen, die sie manipulieren. Ein Objekt ist kein Datenobjekt. Was dann? Ball und Hund In der echten objektorientierten Programmierung sind Objekte Lebewesen, genau wie Sie und ich. Sie sind lebende Organismen mit eigenem Verhalten, eigenen Eigenschaften und eigenem Lebenszyklus. Kann ein lebender Organismus einen Setter haben? Kann man einem Hund einen Ball anbringen („setzen“)? Ich glaube nicht. Aber genau das macht der folgende Code:
Dog dog = new Dog();
dog.setBall(new Ball());
Wie gefällt es dir? Können Sie den Ball aus dem Hund herausbekommen („bekommen“)? Nehmen wir mal an, dass Sie es können. Falls sie es gegessen hat und Sie eine Operation an ihr durchgeführt haben. In diesem Fall können Sie den Ball vom Hund bekommen („holen“). Genau das meine ich:
Dog dog = new Dog();
Ball ball = dog.getBall();
Oder ein noch lächerlicheres Beispiel:
Dog dog = new Dog();
dog.setWeight("23kg");
Können Sie sich das im wirklichen Leben vorstellen? Klingt es so, als würden Sie jeden Tag schreiben? Wenn ja, dann sind Sie ein prozeduraler Programmierer. Gib es einfach zu. Hier ist, was David West auf Seite 30 seines Buches sagt: Der erste Schritt bei der Umwandlung eines erfolgreichen prozeduralen Entwicklers in einen erfolgreichen objektiven Entwickler ist eine Lobotomie. Brauchen Sie eine Lobotomie? Ich brauchte es unbedingt und bekam es, als ich Wests Buch „Object Thinking“ las. Objektives Denken Fangen Sie an, wie ein Objekt zu denken, und Sie werden diese Methoden sofort umbenennen. Das könnten Sie bekommen:
Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();
Jetzt behandeln wir den Hund wie ein echtes Tier, das uns den Ball wegnehmen und ihn zurückgeben kann, wenn wir darum bitten. Nur für den Fall, ich stelle fest, dass der Hund nicht NULL zurückgeben kann. Hunde wissen einfach nicht, was NULL ist! Objektives Denken (Denken) entfernt NULL-Referenzen sofort aus Ihrem Code. Getter/Setter.  Teuflisch.  Und Punkt - 3
Ein Fisch namens Wanda (1988) von Charles Crichton
Darüber hinaus führt objektives Denken zur Unveränderlichkeit eines Objekts, wie in unserem Beispiel das „Gewicht des Hundes“. Sie würden den Code etwa so umschreiben:
Dog dog = new Dog("23kg");
int weight = dog.weight();
Ein Hund ist ein unveränderlicher lebender Organismus, der es niemandem erlaubt, sein Gewicht, seine Größe, seinen Namen usw. zu ändern. Auf Wunsch kann sie ihr Gewicht oder ihren Namen „erzählen“. An öffentlichen Methoden, die Abfragen für bestimmte „interne“ Eigenschaften eines Objekts offenlegen, ist nichts einzuwenden. Diese Methoden sind jedoch keine „Getter“ und sollten niemals das Präfix „get“ erhalten. Wir „kommen“ nicht aus dem Hund heraus. Wir erfahren ihren Namen nicht. Wir bitten sie, uns ihren Namen zu nennen. Sehen Sie den Unterschied? Wir sprechen hier nicht einmal über Semantik. Wir unterscheiden den prozeduralen Ansatz der Programmierung vom objektorientierten. Bei der prozeduralen Programmierung arbeiten wir mit Daten, manipulieren sie, rufen sie ab, setzen sie und löschen sie bei Bedarf. Wir haben das Sagen und Daten sind lediglich eine passive Komponente. Ein Hund bedeutet für uns nichts – er „enthält einfach Daten“. Sie hat kein eigenes Leben. Wir können frei alles, was wir brauchen, daraus bekommen (holen) und beliebige Daten darin ablegen (einstellen). So funktionieren (funktionierten) C, COBOL, Pascal und andere prozedurale Sprachen. Und in der objektorientierten Welt ist die Situation völlig umgekehrt. Hier behandeln wir Objekte als lebende Organismen mit eigenem Geburtsdatum und eigenem Todeszeitpunkt, mit eigener Persönlichkeit und eigenen Gewohnheiten, wenn Sie so wollen. Wir können den Hund bitten, uns Daten zu geben (z. B. sein Gewicht) und er kann die Informationen an uns zurücksenden. Aber denken Sie immer daran, dass der Hund die aktive Komponente ist. Sie entscheidet, was nach der Anfrage passiert. Und deshalb ist es absolut falsch, dass die Methoden eines Objekts mit set oder get beginnen. Dabei geht es nicht einmal um einen Verstoß gegen die Kapselung, wie viele Leute denken. Dabei geht es um die Tatsache, dass Sie entweder wie ein Objekt denken oder immer noch COBOL mit Java-Syntax schreiben. PS . Und ja, Sie fragen sich vielleicht: „Was ist mit JavaBeans, JPA, JAXB und vielen anderen Java-APIs, die von get/set abhängen?“ Was ist mit der in Ruby integrierten Funktion, die das Erstellen von Accessoren erleichtert? Nun, was soll ich Ihnen sagen... Sie haben kein Glück. Es ist viel einfacher, in der primitiven Welt des prozeduralen COBOL zu bleiben, als die wunderbare Welt realer Objekte zu verstehen und anzunehmen. P.P.S. _ Ich habe vergessen zu sagen, ja, das Einfügen von Abhängigkeiten über einen Setter ist auch ein schreckliches Anti-Pattern. Aber mehr dazu im nächsten Beitrag! Originaler Artikel
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION