it-swarm.com.de

Ist es in Ordnung, gegen All-Caps-Namen für Enums vorzugehen, um deren String-Darstellung zu vereinfachen?

Ich habe mehrmals gesehen, wie Leute Titel- oder sogar Kleinbuchstaben für Enum-Konstanten verwenden, zum Beispiel:

enum Color {
  red,
  yellow,
  green;
}

Dies macht das Arbeiten mit ihrer Zeichenfolgenform einfach und unkompliziert, wenn Sie beispielsweise throw new IllegalStateException("Light should not be " + color + ".") ausführen möchten.

Dies scheint akzeptabler zu sein, wenn die Aufzählung private ist, aber ich mag es immer noch nicht. Ich weiß, dass ich einen Enum-Konstruktor mit einem String-Feld erstellen und dann toString überschreiben kann, um diesen Namen wie folgt zurückzugeben:

enum Color {
  RED("red"),
  YELLOW("yellow"),
  GREEN("green");

  private final String name;

  private Color(String name) { 
    this.name = name 
  }

  @Override public String toString() {
    return name; 
  }
}

Aber schauen Sie, wie lange das noch dauert. Es ist ärgerlich, weiterzumachen, wenn Sie ein paar kleine Aufzählungen haben, die Sie einfach halten möchten. Ist es in Ordnung, hier nur unkonventionelle Fallformate zu verwenden?

14
codebreaker

Die kurze Antwort ist natürlich, ob Sie mit Namenskonventionen für im Wesentlichen Konstanten brechen möchten ... Zitieren aus dem JLS :

Konstante Namen

Die Namen von Konstanten in Schnittstellentypen sollten und Endvariablen von Klassentypen üblicherweise eine Folge von einem oder mehreren Wörtern, Akronymen oder Abkürzungen sein, alle in Großbuchstaben, wobei die Komponenten durch Unterstriche "_" getrennt sind. Konstante Namen sollten beschreibend sein und nicht unnötig abgekürzt werden. Herkömmlicherweise können sie ein geeigneter Teil der Rede sein.

Die lange Antwort in Bezug auf die Verwendung von toString() ist, dass dies definitiv die Methode ist, die überschrieben werden muss, wenn Sie eine mehr lesbare Darstellung der enum -Werte wünschen. Zitat aus Object.toString() (Hervorhebung von mir):

Gibt eine Zeichenfolgendarstellung des Objekts zurück. Im Allgemeinen gibt die Methode toString eine Zeichenfolge zurück, die dieses Objekt "textuell darstellt" . Das Ergebnis sollte eine präzise, ​​aber informative Darstellung sein, die für eine Person leicht zu lesen ist . Es wird empfohlen, dass alle Unterklassen diese Methode überschreiben.

Ich bin mir nicht sicher, warum einige der Antworten darauf abzielten, über das Konvertieren von enums mit String -Werten hin und her zu sprechen, aber ich werde auch hier nur meine Meinung dazu abgeben. Eine solche Serialisierung von enum -Werten kann leicht mit den Methoden name() oder ordinal() durchgeführt werden. Beide sind final und somit können Sie sicher sein, dass die zurückgegebenen Werte solange sich die Namen oder die Position der Werte nicht ändern. Für mich ist das ein klarer Marker.

Was ich aus dem Obigen zusammenfasse, ist: Heute möchten Sie YELLOW vielleicht einfach als "gelb" beschreiben. Morgen möchten Sie es vielleicht als "Pantone Minion Yellow" beschreiben. Diese Beschreibungen sollten vom Aufruf von toString() zurückgegeben werden, und ich würde nicht erwarten, dass sich name() oder ordinal() ändern. Wenn ich das tue, muss ich das in meiner Codebasis oder in meinem Team lösen, und wird zu einer größeren Frage als nur ein enum Namensstil.

Wenn Sie lediglich eine lesbare Darstellung Ihrer enum -Werte protokollieren möchten, empfehle ich dennoch, sich an die Konventionen zu halten und dann die toString(). Wenn Sie sie auch in eine Datendatei oder in andere Nicht-Java-Ziele serialisieren möchten, verfügen Sie weiterhin über die Methoden name() und ordinal(), um Sie zu sichern, sodass dies nicht erforderlich ist Bund über überschreiben toString().

14
h.j.k.

Ändern Sie nicht ENUM, das ist nur schlechter Code-Geruch. Sei eine Aufzählung eine Aufzählung und eine Zeichenfolge eine Zeichenfolge.

Verwenden Sie stattdessen einen CamelCase-Konverter für Zeichenfolgenwerte.

throw new IllegalStateException("Light should not be " + CamelCase(color) + ".");

Es gibt viele Open Source-Bibliotheken, die dieses Problem bereits für Java lösen.

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CaseFormat.html

5
Reactgular

Wenn ich Aufzählungen zwischen meinem Java Code und einer Datenbank- oder Client-App sende), lese und schreibe ich die Aufzählungswerte häufig als Zeichenfolgen. toString() wird beim Verketten von Zeichenfolgen implizit aufgerufen. Überschreiben toString () in einigen Enums bedeutete, dass ich manchmal einfach konnte

"<input type='checkbox' value='" + MY_CONST1 + "'>"

und manchmal musste ich daran denken anzurufen

"<input type='checkbox' value='" + MY_CONST1.name() + "'>"

was zu Fehlern führte, also mache ich das nicht mehr. Eigentlich überschreibe ich any Methoden in Enum nicht, denn wenn Sie sie auf genügend Client-Code übertragen, werden Sie möglicherweise die Erwartungen von jemandem brechen.

Erstellen Sie Ihren eigenen neuen Methodennamen, z. B. public String text() oder toEnglish() oder was auch immer.

Hier ist eine kleine Hilfsfunktion, die Ihnen das Tippen ersparen könnte, wenn Sie viele Aufzählungen wie die oben genannten haben:

public static String ucFirstLowerRest(String s) {
    if ( (s == null) || (s.length() < 1) ) {
        return s;
    } else if (s.length() == 1) {
        return s.toUpperCase();
    } else {
        return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
    }
}

Es ist immer einfach, .toUpperCase () oder .toLowerCase () aufzurufen, aber es kann schwierig sein, gemischte Groß- und Kleinschreibung zurückzugewinnen. Betrachten Sie die Farbe "bleu de France". Frankreich wird immer groß geschrieben, daher möchten Sie Ihrer Aufzählung möglicherweise eine textLower () -Methode hinzufügen, wenn Sie darauf stoßen. Wenn Sie diesen Text am Anfang eines Satzes oder in der Mitte eines Satzes oder in einem Titel verwenden, können Sie sehen, wie eine einzelne toString() -Methode zu kurz kommt. Und das berührt nicht einmal Zeichen, die in Java Bezeichner) illegal sind oder deren Eingabe schwierig ist, weil sie nicht auf Standardtastaturen dargestellt werden, oder Zeichen ohne Groß-/Kleinschreibung ( Kanji usw.).

enum Color {
  BLEU_DE_FRANCE {
    @Override public String textTc() { return "Bleu De France"; }
    @Override public String textLc() { return "bleu de France"; }
  }
  CAFE_NOIR {
    @Override public String textTc() { return "Café Noir"; }
  }
  RED,
  YELLOW,
  GREEN;

  // The text in title case
  private final String textTc;

  private Color() { 
    textTc = ucFirstLowerRest(this.toString());
  }

  // Title case
  public String textTc() { return textTc; }

  // For the middle of a sentence
  public String textLc() { return textTc().toLowerCase(); }

  // For the start of a sentence
  public String textUcFirst() {
    String lc = textLc();
    return lc.substring(0, 1).toUpperCase() + lc.substring(1);
  }
}

Es ist nicht so schwierig, diese richtig zu verwenden:

IllegalStateException(color1.textUcFirst() + " clashes horribly with " +
                      color2.textLc() + "!")

Hoffentlich zeigt dies auch, warum die Verwendung von Enum-Werten in gemischten Groß- und Kleinschreibung Sie ebenfalls enttäuschen wird. Ein letzter Grund, bei All-Caps mit Unterstrichen Enum-Konstanten zu bleiben, ist, dass dies dem Prinzip des geringsten Erstaunens folgt. Die Leute erwarten es. Wenn Sie also etwas anderes tun, müssen Sie sich immer selbst erklären oder mit Leuten umgehen, die Ihren Code missbrauchen.

3
GlenPeterson

Das Befolgen der UPPERCASE-Namenskonvention verstößt möglicherweise gegen DRY . (Und YAGNI ). B. in Ihrem Codebeispiel Nr. 2: "ROT" und "Rot" werden wiederholt.

Befolgen Sie also die offizielle Konvention oder DRY? Ihr Anruf.

In meinem Code werde ich DRY folgen. Ich werde jedoch einen Kommentar zur Enum-Klasse abgeben und sagen: "Nicht alle Großbuchstaben, weil (Erklärung hier)"

0
user949300

Wenn die geringste Wahrscheinlichkeit besteht, dass diese Zeichenfolgendarstellungen an Orten wie Datenbanken oder Textdateien gespeichert werden, ist es äußerst problematisch, sie an die tatsächlichen Aufzählungskonstanten zu binden, wenn Sie Ihre Aufzählung jemals umgestalten müssen.

Was ist, wenn Sie eines Tages beschließen, Color.White In Color.TitaniumWhite Umbenennen, während es Datendateien gibt, die "Weiß" enthalten?

Sobald Sie mit der Konvertierung von Enum-Konstanten in Zeichenfolgen beginnen, besteht der nächste Schritt darin, Zeichenfolgen zu generieren, die der Benutzer sehen kann. Das Problem hier ist, wie Sie sicher bereits wissen, die Syntax von Java erlaubt keine Leerzeichen innerhalb von Bezeichnern. (Sie werden niemals Color.Titanium White Haben.) Da Sie wahrscheinlich einen geeigneten Mechanismus zum Generieren von Aufzählungsnamen benötigen, um sie dem Benutzer anzuzeigen, ist dies am besten um zu vermeiden, dass Ihre Aufzählung unnötig kompliziert wird.

Nachdem dies gesagt wurde, können Sie natürlich weitermachen und das tun, woran Sie gedacht haben, und später Ihre Aufzählung umgestalten, um dem Konstruktor Namen zu geben, wenn (und wenn) Sie in Schwierigkeiten geraten.

Sie können ein paar Zeilen von Ihrem Enum-with-Konstruktor entfernen, indem Sie das Feld namepublic final Deklarieren und den Getter verlieren. (Was ist diese Liebe, die Java Programmierer gegenüber Gettern haben?)

0
Mike Nakis