Wir hatten vor kurzem einen Code-Review. Eine meiner Klassen wurde verwendet, so dass ich mehr als einen Datentyp von/zu Methoden zurückgeben/übergeben konnte. Die einzigen Methoden, die die Klasse hatte, waren Getter/Setter. Ein Mitglied des Teams (dessen Meinung ich respektiere) sagte, dass eine solche Klasse eine schlechte Übung sei (und nicht sehr OOP). Warum das ?Warum wird in Java eine Klasse als eine struct-schlechte Methode verwendet?
Antwort
Es gibt ein Argument, dass Klassen entweder "Datenstrukturen" (d. H. Konzentrieren sich auf das Speichern von Daten ohne Funktionalität) oder "Funktionalität orientiert" sein sollten (d. H. Konzentrieren sich auf die Durchführung bestimmter Aktionen beim Speichern minimaler Zustand). Wenn Sie diesem Argument folgen (was sinnvoll ist, aber nicht immer einfach ist), dann ist damit nichts falsch.
In der Tat würde man argumentieren, dass Bohnen und Entity Bohnen sind im Wesentlichen das - Datenbehälter mit Getter und Setter.
Ich habe bestimmte Quellen gesehen (z. B. das Buch "clean code") argumentieren, dass man Methoden mit mehreren Parametern vermeiden sollte und stattdessen sie als ein einzelnes Objekt mit Getter und Setter übergeben. Dies ist auch näher am "Smalltalk-Modell" der benannten Parameter, bei denen die Reihenfolge keine Rolle spielt.
Also ich denke, dass bei richtiger Verwendung, Ihr Design sinnvoll ist.
Im Allgemeinen möchten Sie das Wissen isolieren, das benötigt wird, um mit einer Klasse in der Klasse selbst zu arbeiten. Wenn Sie eine Klasse wie diese haben, wird sie entweder an mehreren Stellen verwendet und kann daher einige der Funktionen an diesen beiden Stellen übernehmen, oder sie befindet sich an einem einzigen Ort und sollte eine innere Klasse sein. Wenn es auf mehrere Arten verwendet wird, aber auf völlig unterschiedliche Weise, so dass es keine gemeinsam genutzte Funktionalität gibt, ist die Tatsache, dass es sich um eine einzelne Klasse handelt, irreführend, was auf eine gemeinsame Funktionalität hinweist, wo es keine gibt.
Es gibt jedoch oft spezifische Gründe dafür, wo diese allgemeinen Regeln gelten oder nicht, und es hängt davon ab, was Ihre Klasse repräsentieren sollte.
Ich denke, er könnte "nicht sehr OOP" für schlechte Praxis verwirren. Ich denke, er hat erwartet, dass Sie mehrere Methoden bereitstellen, die jeweils 1 Wert zurückgeben, der benötigt wurde (da Sie sie sowieso in Ihrer neuen Klasse verwenden müssen, ist das nicht so schlimm).
Beachten Sie, dass Sie in diesem Fall wahrscheinlich keine Getter/Setter verwenden sollten, machen Sie die Daten nur öffentlich. Nein, das ist "nicht sehr OOP", aber das ist der richtige Weg.
Vielleicht bietet Josh Bloch einen Einblick in diese here.
Beachten Sie, dass hier zwei separate Probleme auftreten.
Ist eine "struct-like" Klasse sinnvoll?
Erstellt eine Klasse, um mehrere Werte aus einer Methode sinnvoll zurückzugeben?
Struct-Klassen wie
Eine Objektklasse sollen - zum größten Teil - stellen eine Klasse von Objekten der realen Welt. Eine passive, struct-like Java Bean (alle Getter und Setter) Mai repräsentieren eine reale Sache.
Allerdings haben die meisten realen Dinge Regeln, Einschränkungen, Verhaltensweisen und grundlegende Verben, in die sie eingreifen. Eine Struktur-ähnliche Klasse ist selten eine gute Übereinstimmung für eine reale Sache, es ist normalerweise etwas technisches. Das macht es weniger als ideale OO-Design.
Multiple kehrt von einer Methode
Während Python dies hat, funktioniert Java nicht. Mehrere Rückgabewerte sind keine OO-Frage, per se. Es ist eine Frage der sprachlichen Einschränkungen.
Mehrere Rückgabewerte können bedeuten, dass ein Objekt den Status geändert hat. Vielleicht ändert eine Methode den Zustand und eine Gruppe von Gettern gibt die Werte zurück, die von dieser Zustandsänderung stammen.
Python erlaubt nicht wirklich mehrere Rückgabewerte, es wickelt es in einen einzigen Typ, Tupel, und erlaubt Tupel/Listen, die mehreren Variablen in einer Anweisung zugewiesen werden. –
@he_the_great: obwohl wahr, ist es eine Unterscheidung, die so subtil ist, um für diese Situation fast keinen Wert zu haben. Das Problem besteht darin, OO-Design und Java-Einschränkungen zu vereinen. Python ist OO, geht aber bei einigen Dingen anders vor. –
Um ehrlich zu sein, es klingt gut für mich. Welche Alternative hat der Rezensent vorgeschlagen?
Nach OOP "Best Practices" und alles ist in Ordnung, aber Sie müssen pragmatisch sein und tatsächlich die Arbeit erledigt.
Verwenden von Value Objekte wie diese (OO sprechen für 'struct') ist in einigen Fällen ein vollkommen legitimer Ansatz.
- 1. Warum wird eine globale Variablenklasse (Singleton) als schlechte Methode verwendet?
- 2. Java: Herausfinden, warum * eine Klasse geladen wird
- 3. Xcode, sehen, wo eine Methode verwendet wird
- 4. Wie verwendet eine Klasse eine Methode, die in Java in einer anderen Klasse definiert ist?
- 5. Warum sollte man eine Java-Interface-Methode als abstrakt deklarieren?
- 6. Übergabe einer Klasse als Argument an eine Methode in Java
- 7. Warum wird die Klasse in Java als statisch deklariert?
- 8. Warum verwendet meine Getter Magic-Methode eine Klasseninstanz als Index?
- 9. Wie wird eine Header-Datei richtig als vollständige Klasse verwendet?
- 10. Warum benötigt eine Klasse, die als Wert in einer STL-Map verwendet wird, einen Standardkonstruktor in ...?
- 11. eine Methode als eine Membervariable einer Klasse in C# Speichern
- 12. Warum kann eine Klasse mit einem Typparameter, der ausschließlich als Argumenttyp verwendet wird, nicht kovariant sein?
- 13. Java Optional warum nicht eine ifNotPresent-Methode?
- 14. Wofür wird die Java-Klasse "Context" verwendet?
- 15. Warum Aufrufmethode mit generischer Rückgabe für eine generische Klasse wird von Java als unsicher angesehen?
- 16. Warum wird nicht initialisiert als eine Methode angezeigt, wenn ich die Instanzmethoden einer Klasse aufrufen?
- 17. Warum verwendet six.py eine benutzerdefinierte Klasse zum Suchen von MAXSIZE?
- 18. Eine Java-Methode überschreiben
- 19. Wie verwendet man eine andere Klasse in httpPost Methode
- 20. Java: Anonyme innere Klasse, die eine lokale Variable verwendet
- 21. Sollte eine Methode Klasse oder Klasse <?> zurückgeben?
- 22. Ist es eine Methode oder eine Klasse?
- 23. Kann eine void-Methode in einer Klasse in Java
- 24. Eine statische Methode in einer Klasse deklarieren und als Methode einer anderen Klasse verwenden
- 25. Warum verwendet eine native Bibliothek 1,5 Mal mehr Speicher, wenn sie von Java verwendet wird, als wenn sie von einem C-Programm unter Linux verwendet wird?
- 26. Warum wird Java häufig für Unternehmensanwendungen verwendet?
- 27. Wie verhindert man, dass eine Methode in Java überlastet wird?
- 28. Wie erzwinge ich, dass eine Methode in Java überschrieben wird?
- 29. Warum wird eine Ladenladeschranke als teuer angesehen?
- 30. Was nutzt eine Methode-lokale innere Klasse?
Obwohl ich nicht unbedingt mit der Klassenunterteilung zwischen "Staat" und "Funktionalität" nicht einverstanden bin, muss ich darauf hinweisen, dass dies das OO aus dem OO herausholt. – Zarkonnen
Ich denke, die allgemeine Idee hinter dieser Trennung ist es, ein Objekt mit Nicht-Kern-Funktionalität nicht zu überlasten und stattdessen diese Art von "Funktoren" als Klassen zu betrachten. – Uri
Ich würde nur Strukturen verwenden, wenn die Felder/Eigenschaften keine Referenztypen sind. Auf diese Weise werden Daten als Parameter übergeben. Die aufgerufene Methode erhält eine Kopie der Daten anstelle einer Referenz (wie die Übergabe einer Instanz einer Klasse) und kann die ursprünglichen Daten nicht ändern. Wenn Sie dieselbe Strukturinstanz bei mehreren Aufrufen erneut verwenden, wirkt sich dies nicht gegenseitig aus. Ein gutes Beispiel für eine Struktur könnte etwas sein wie: Vector (das ist eine Menge von Floats, die einen Vektor darstellen) –