Warum Enums anstelle von Konstanten verwenden? Welches ist besser in Bezug auf Software-Design und Lesbarkeit

77

Ich habe ein Szenario , in dem ich Spielertyp ARCHER , WARRIORund sorcerer.
Was soll ich in der Spielerklasse für einen Spielertyp verwenden?
Konstante endgültige statische String- Variable oder eine Aufzählung ? und warum?
Bitte helfen Sie mit Gründen.

Waqas
quelle
1
Ich würde keine String-Variable verwenden. Wenn überhaupt, eine intVariable (mit gut benannten Konstanten für die verschiedenen Typen).
Thilo
6
Ist diese Antwort gut für dich? stackoverflow.com/questions/613837/…
Jimmy
mögliches Duplikat von Wofür ist Enum nützlich?
Oers
1
@RBz Das ändert nichts an der Tatsache, dass die Aufzählungen in Java ganz andere Tiere sind als die Aufzählungen in C # und anderen C-ähnlichen Sprachen. Und obwohl es als sprachunabhängig gekennzeichnet ist, sind die Antworten auf diese Frage alle C # -spezifisch.
Mark Rotteveel

Antworten:

135

Angenommen, Sie verwenden konstante Zeichenfolgen (oder intWerte - das gilt auch für sie):

// Constants for player types
public static final String ARCHER = "Archer";
public static final String WARRIOR = "Warrior";

// Constants for genders
public static final String MALE = "Male";
public static final String FEMALE = "Female";

Dann kennen Sie den Typ Ihrer Daten nicht wirklich - was zu möglicherweise falschem Code führt:

String playerType = Constants.MALE;

Wenn Sie Aufzählungen verwenden, würde dies wie folgt enden:

// Compile-time error - incompatible types!
PlayerType playerType = Gender.MALE;

Ebenso geben Aufzählungen einen eingeschränkten Satz von Werten an:

String playerType = "Fred"; // Hang on, that's not one we know about...

vs.

PlayerType playerType = "Fred"; // Nope, that doesn't work. Bang!

Darüber hinaus können Aufzählungen in Java mehr Informationen enthalten und auch Verhalten aufweisen. Rundum viel besser.

Jon Skeet
quelle
4
Was ist mit dem Leistungsvergleich zwischen Aufzählungen und Konstanten?
Waqas
1
@ waqas716: Aufzählungen sind Referenztypen, aber es gibt nur ein Objekt pro Wert, sodass Sie wahrscheinlich nicht viel Speicher verschwenden. Wenn Sie andere Leistungsunterschiede wünschen, müssen Sie sagen, woran Sie interessiert sind.
Jon Skeet
1
Ich muss dieses Player-Objekt an einen webService senden. Daher werde ich dieses Objekt in einen Json-String konvertieren. Was soll ich in diesem Fall für String-Konstanten oder Enum verwenden?
Waqas
Sie können jederzeit eine Karte verwenden, um von Enums zu Strings zu gelangen. (In Apaches Commons Collections 4 gibt es auch eine bidirektionale Karte, mit der Sie bei Bedarf von Strings zu Enums wechseln können: commons.apache.org/proper/commons-collections/apidocs/org/… )
Jacob Holloway
13

Enums beschränken Sie auf die erforderlichen Eingaben, während Sie auch bei Verwendung konstanter Zeichenfolgen andere Zeichenfolgen verwenden können, die nicht Teil Ihrer Logik sind.

Dies hilft Ihnen, keinen Fehler zu machen, etwas außerhalb der Domäne einzugeben, während Sie Daten eingeben, und verbessert auch die Lesbarkeit des Programms.

Außerdem können Sie Ihre Aufzählungen jederzeit als Zeichenfolge verwenden, wenn Sie dies wünschen. Hier ist eine Referenz .

Nitin Chhajer
quelle
6

Abgesehen davon, dass Sie keinen falschen Wert angeben dürfen, gibt es noch eine weitere Funktion von Aufzählungen, die zwar geringfügig erscheint, aber meiner Meinung nach sehr wichtig ist. Moderne IDEs können automatisch Werte für Aufzählungen vorschlagen, während es keine Möglichkeit gibt, die möglichen Werte einer Zeichenfolgenkonstante zuverlässig abzuleiten (Intellij IDEA führt Letzteres aus, jedoch nur für JDK-Klassen und gängige Bibliotheken). Dies ist besonders hilfreich, wenn Sie eine neue API untersuchen.

NewlessClubie
quelle
2

Enum ist besser für die Typensicherheit zu verwenden. Es können keine falschen Werte eingegeben werden. Aber Enum in Android benötigt so viel Speicher, dass Sie stattdessen intdef verwenden sollten. In dieser Antwort finden Sie ein Beispiel und eine Erklärung: -

IntDef / StringDef-Beispiel

Sie können auch den Android-Quellcode überprüfen, der nach Möglichkeit Enums durch IntDef / StringDef ersetzt. Ex. View.VISIBLE.

Harish Gyanani
quelle
0

Ich würde Ihnen raten, Aufzählungen nur zu verwenden, wenn Sie wirklich aufgezählte Konstanten oder zusätzliche Funktionen benötigen, die allen Elementen gemeinsam sind.

Dies hängt natürlich von der Art der Anwendung ab, die Sie schreiben, und davon, welche Versionen und Geräte Sie unterstützen möchten.

Der Grund dafür ist, dass Aufzählungen zusätzlichen Aufwand verursachen, da sie Instanzen ihrer Elemente zuweisen. Sie können feststellen, dass es in der Android-Plattform minimale Aufzählungen gibt und fast alle Konstanten endgültige statische Ints sind (wie View.GONE und ähnliches).

Alex Orlov
quelle
2
@ Jon Skeet: Was sagst du dazu?
Waqas
1
Manchmal ist die Typensicherheit die Kosten des "zusätzlichen Overheads" wert.
Michael Campbell