2008-11-23 6 views
13

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

14

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.

+0

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

+0

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

+0

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) –

1

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.

0

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.

0

Vielleicht bietet Josh Bloch einen Einblick in diese here.

4

Beachten Sie, dass hier zwei separate Probleme auftreten.

  1. Ist eine "struct-like" Klasse sinnvoll?

  2. 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.

+0

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. –

+0

@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. –

3

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.

Verwandte Themen