370 Stimmen

Wie lassen sich Konstanten am besten in Java implementieren?

Ich habe solche Beispiele gesehen:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

und nahm an, dass ich eine Klasse Constants haben könnte, um Konstanten darin zu verpacken und sie als static final zu deklarieren. Ich weiß praktisch kein Java überhaupt und frage mich, ob dies der beste Weg, um Konstanten zu erstellen ist.

0voto

Quinn Turner Punkte 232

Ich stimme dem zu, was die meisten sagen, es ist am besten, Enums zu verwenden, wenn es um eine Sammlung von Konstanten geht. Allerdings, wenn Sie in Android programmieren, gibt es eine bessere Lösung: IntDef-Anmerkung .

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

Die IntDef-Annotation ist den Enums in einer einfachen Hinsicht überlegen: Sie benötigt deutlich weniger Platz, da sie lediglich eine Kompilierzeitmarkierung ist. Sie ist keine Klasse und hat auch nicht die Eigenschaft der automatischen String-Konvertierung.

0voto

Blessed Geek Punkte 19927

Sie ist BAD habit and terribly ANNOYING Praxis Joshua Bloch zu zitieren, ohne die Grundlagen des Fundamentalismus zu verstehen.

Ich habe nichts von Joshua Bloch gelesen, also entweder

  • er ist ein schrecklicher Programmierer
  • oder die Leute, die ich bisher gefunden habe, die ihn zitieren (Joshua ist der Name eines Jungen, nehme ich an), benutzen sein Material einfach als religiöse Schriften, um ihre religiösen Software-Ablässe zu rechtfertigen.

Wie im biblischen Fundamentalismus lassen sich alle biblischen Gesetze zusammenfassen mit

  • Liebe die grundlegende Identität mit deinem ganzen Herzen und deinem ganzen Verstand
  • Liebe deinen Nächsten wie dich selbst

und so lässt sich auch der Fundamentalismus der Softwaretechnik wie folgt zusammenfassen

  • sich mit ganzer Kraft und ganzem Verstand den Grundlagen der Programmierung widmen
  • und widmen Sie sich der Exzellenz Ihrer Mitprogrammierer, wie Sie es für sich selbst tun würden.

Auch in bibelfundamentalistischen Kreisen wird eine starke und vernünftige Konsequenz gezogen

  • Lieben Sie zuerst sich selbst. Denn wenn man sich selbst nicht sehr liebt, dann hat das Konzept "Liebe deinen Nächsten wie dich selbst" kein großes Gewicht, denn "wie sehr du dich selbst liebst" ist die Bezugslinie, über der du andere lieben würdest.

Ähnlich verhält es sich, wenn Sie sich selbst nicht als Programmierer respektieren und einfach die Verlautbarungen und Prophezeiungen irgendeines Programmiergurus akzeptieren, OHNE die Grundlagen zu hinterfragen. Dann sind Ihre Zitate und Ihr Vertrauen in Joshua Bloch (und dergleichen) bedeutungslos. Und deshalb haben Sie auch keinen Respekt vor Ihren Programmiererkollegen.

Die grundlegenden Gesetze der Softwareprogrammierung

  • Faulheit ist die Tugend eines guten Programmierers
  • Sie sollen Ihr Leben als Programmierer so einfach, so faul und damit so effektiv wie möglich gestalten
  • Sie sollen die Folgen und Eingeweide Ihrer Programmierung für Ihre Programmiernachbarn, die mit Ihnen arbeiten und Ihre Programmiereingeweide aufgreifen, so einfach, so faul und damit so effektiv wie möglich machen.

Schnittstellen-Musterkonstanten sind eine schlechte Angewohnheit.

Unter welche Gesetze einer grundsätzlich wirksamen und verantwortungsvollen Programmierung fällt dieses religiöse Edikt?

Lesen Sie einfach den Wikipedia-Artikel über Schnittstellen-Musterkonstanten ( https://en.wikipedia.org/wiki/Constant_interface ), und die dummen Ausreden, die es gegen Schnittstellen-Musterkonstanten vorbringt.

  • Was wäre wenn - keine IDE? Wer, um alles in der Welt, würde als Softwareprogrammierer keine IDE benutzen? Die meisten von uns sind Programmierer, die es vorziehen, ihren machohaften Überlebenswillen nicht unter Beweis stellen zu müssen, indem sie die Verwendung einer IDE vermeiden.

    • Und - Moment mal - Befürworter der mikrofunktionalen Programmierung als Mittel, um keine IDE zu benötigen. Warten Sie, bis Sie meine Erklärung zur Normalisierung von Datenmodellen gelesen haben.
  • Verschmutzt den Namensraum mit Variablen, die im aktuellen Bereich nicht verwendet werden? Es könnten Befürworter dieser Meinung sein

    • sich der Notwendigkeit der Normalisierung von Datenmodellen nicht bewusst sind
  • Die Verwendung von Schnittstellen zur Erzwingung von Konstanten ist ein Missbrauch von Schnittstellen. Die Befürworter solcher Schnittstellen haben die schlechte Angewohnheit

    • nicht sehen, dass "Konstanten" als Vertrag behandelt werden müssen. Und Schnittstellen dienen dazu, die Einhaltung eines Vertrages zu erzwingen oder zu projizieren.
  • Es ist schwierig, wenn nicht gar unmöglich, Schnittstellen in Zukunft in implementierte Klassen umzuwandeln. Hah .... hmmm ... ??

    • Warum sollten Sie sich auf ein solches Programmierungsmuster einlassen wollen, um Ihren Lebensunterhalt zu bestreiten? D.h., warum sollten Sie sich einer solchen AMBIVALENTEN und schlechten Programmiergewohnheit widmen?

Was auch immer die Ausreden sein mögen, es gibt KEINE GRÜNDLICHE AUSRECHNUNG, wenn es um GRUNDSÄTZLICH EFFEKTIVE Softwareentwicklung geht, um die Verwendung von Schnittstellenkonstanten zu delegitimieren oder generell davon abzuraten.

Es spielt keine Rolle, was die ursprünglichen Absichten und Gedankengänge der Gründerväter waren, die die Verfassung der Vereinigten Staaten ausgearbeitet haben. Wir können über die ursprünglichen Absichten der Gründerväter diskutieren, aber mich interessieren nur die schriftlichen Aussagen der US-Verfassung. Und es liegt in der Verantwortung eines jeden US-Bürgers, den geschriebenen literarischen Fundamentalismus und nicht die ungeschriebenen Gründungsabsichten der US-Verfassung zu nutzen.

Ebenso wenig interessiert mich, was die "ursprünglichen" Absichten der Gründer der Java-Plattform und der Programmiersprache für die Schnittstelle waren. Was mich interessiert, sind die effektiven Funktionen, die die Java-Spezifikation bietet, und ich beabsichtige, diese Funktionen in vollem Umfang zu nutzen, um die grundlegenden Gesetze der verantwortungsvollen Softwareprogrammierung zu erfüllen. Es ist mir egal, ob der Eindruck entsteht, dass ich "die Intention für Schnittstellen verletze". Es ist mir egal, was Gosling oder ein gewisser Bloch über die "richtige Art und Weise, Java zu benutzen" sagt, es sei denn, das, was sie sagen, verstößt nicht gegen mein Bedürfnis nach EFFEKTIVER Erfüllung der Grundlagen.

Die Grundlage ist die Normalisierung des Datenmodells

Es spielt keine Rolle, wie Ihr Datenmodell gehostet oder übertragen wird. Ob Sie Schnittstellen oder Enums oder was auch immer verwenden, relational oder kein SQL, wenn Sie die Notwendigkeit und den Prozess der Normalisierung von Datenmodellen nicht verstehen.

Wir müssen zunächst das Datenmodell einer Reihe von Prozessen definieren und normalisieren. Und wenn wir ein kohärentes Datenmodell haben, können wir NUR dann den Prozessfluss seiner Komponenten verwenden, um das funktionale Verhalten und die Prozessblöcke eines Feldes oder Bereichs von Anwendungen zu definieren. Und erst dann können wir die API eines jeden funktionalen Prozesses definieren.

Sogar die Facetten der Datennormalisierung, wie sie von EF Codd vorgeschlagen wurden, werden heute ernsthaft in Frage gestellt. So wurde z.B. seine Aussage über 1NF als zweideutig, falsch ausgerichtet und zu sehr vereinfacht kritisiert, ebenso wie der Rest seiner Aussagen, insbesondere im Aufkommen moderner Datendienste, Repo-Technologie und Übertragung. IMO sollten die EF Codd-Aussagen vollständig gestrichen und neue, mathematisch plausiblere Aussagen entwickelt werden.

Ein eklatanter Fehler von EF Codd und die Ursache für seine Fehlanpassung an ein effektives menschliches Verständnis ist sein Glaube, dass menschlich wahrnehmbare mehrdimensionale, veränderbare Daten effizient durch eine Reihe von stückweisen zweidimensionalen Zuordnungen wahrgenommen werden können.

Die Grundlagen der Datennormalisierung

Was EF Codd nicht zum Ausdruck gebracht hat.

Innerhalb jedes kohärenten Datenmodells sind diese die sequentiell abgestufte Reihenfolge der zu erreichenden Datenmodellkohärenz.

  1. Die Einheit und Identität von Dateninstanzen.
    • die Granularität jeder Datenkomponente so gestalten, dass jede Instanz einer Komponente eindeutig identifiziert und abgerufen werden kann.
    • kein Instanz-Aliasing, d. h. es gibt keine Möglichkeit, dass eine Identifizierung mehr als eine Instanz einer Komponente erzeugt.
  2. Abwesenheit von Instanzübersprechen. Es besteht nicht die Notwendigkeit, eine oder mehrere andere Instanzen einer Komponente zu verwenden, um zur Identifizierung einer Instanz einer Komponente beizutragen.
  3. Die Einheit und Identität von Datenkomponenten/Dimensionen.
    • Vorhandensein von Komponenten-Entzerrung. Es muss eine Definition geben, mit der eine Komponente/Dimension eindeutig identifiziert werden kann. Dies ist die primäre Definition einer Komponente;
    • wo die primäre Definition nicht dazu führt, dass Unterdimensionen oder Mitgliedskomponenten, die nicht Teil einer beabsichtigten Komponente sind, sichtbar werden;
  4. Einzigartiges Mittel für den Umgang mit Komponenten. Für eine Komponente darf es nur eine, und nur eine, solche Definition des Komponenten-Dealiasing geben.
  5. Es gibt eine, und nur eine, Definitionsschnittstelle oder einen Vertrag, um eine übergeordnete Komponente in einer hierarchischen Beziehung von Komponenten zu identifizieren.
  6. Kein Übersprechen der Komponenten. Es besteht nicht die Notwendigkeit, ein Mitglied einer anderen Komponente zu verwenden, um zur endgültigen Identifizierung einer Komponente beizutragen.
    • In einer solchen Eltern-Kind-Beziehung darf die identifizierende Definition eines Elternteils nicht von einem Teil der Menge der Mitgliedskomponenten eines Kindes abhängen. Eine Mitgliedskomponente der Identität eines Elternteils muss die vollständige Identität des Kindes sein, ohne auf eines oder alle Kinder des Kindes zu verweisen.
  7. Vorbeugung gegen bi- oder multimodale Erscheinungen eines Datenmodells.
    • Wenn es zwei Definitionskandidaten für eine Komponente gibt, ist dies ein deutliches Zeichen dafür, dass zwei verschiedene Datenmodelle als eines vermischt werden. Das bedeutet, dass eine Inkohärenz auf der Ebene des Datenmodells oder des Feldes vorliegt.
    • Ein Anwendungsbereich muss ein einziges, kohärentes Datenmodell verwenden.
  8. Erkennung und Identifizierung von Komponentenmutationen. Solange Sie keine statistische Komponentenanalyse großer Datenmengen durchgeführt haben, sehen Sie wahrscheinlich keine Komponentenmutation oder sehen keine Notwendigkeit, sie zu behandeln.
    • Bei einem Datenmodell können sich einige seiner Komponenten zyklisch oder schrittweise verändern.
    • Der Modus kann Gliederrotation oder Transpositionsrotation sein.
    • Die Mutation der Mitglieder könnte ein eindeutiger Austausch von Kindkomponenten zwischen Komponenten sein. Oder es müssten völlig neue Komponenten definiert werden.
    • Eine Transpositionsmutation würde sich darin äußern, dass ein Dimensionsglied zu einem Attribut mutiert und umgekehrt.
    • Jeder Mutationszyklus muss als eigenes Datenmodal identifiziert werden.
  9. Versionieren Sie jede Mutation. So können Sie eine frühere Version des Datenmodells herausziehen, wenn vielleicht die Notwendigkeit entsteht, eine 8 Jahre alte Mutation des Datenmodells zu behandeln.

In einem Feld oder Netz von Komponenten-Anwendungen, die sich gegenseitig bedienen, muss es ein einziges kohärentes Datenmodell geben, oder es muss ein Mittel vorhanden sein, mit dem sich ein Datenmodell/eine Version selbst identifizieren kann.

Fragen wir immer noch, ob wir Schnittstellenkonstanten verwenden können? Wirklich?

Es gibt Probleme mit der Datennormalisierung, die weit über diese banale Frage hinausgehen. WENN Sie diese Probleme nicht lösen, ist die Verwirrung, die die Schnittstellenkonstanten Ihrer Meinung nach verursachen, vergleichsweise gering. Nix.

Aus der Datenmodellnormalisierung bestimmen Sie dann die Komponenten als Variablen, als Eigenschaften, als Vertragsschnittstellenkonstanten.

Dann bestimmen Sie, was in die Wertinjektion, die Eigenschaftskonfiguration, die Schnittstellen, die endgültigen Zeichenketten usw. eingeht.

Wenn Sie die Ausrede benutzen müssen, dass Sie eine Komponente leichter finden müssen, um gegen Schnittstellenkonstanten zu diktieren, bedeutet das, dass Sie die schlechte Angewohnheit haben, keine Datenmodellnormalisierung zu praktizieren.

Vielleicht möchten Sie das Datenmodell in ein vcs-Release kompilieren. So können Sie eine eindeutig identifizierbare Version eines Datenmodells herausziehen.

Bei Werten, die in Schnittstellen definiert sind, ist sichergestellt, dass sie nicht veränderbar sind. Und gemeinsam nutzbar. Warum sollten Sie einen Satz endgültiger Zeichenketten aus einer anderen Klasse in Ihre Klasse laden, wenn Sie nur diesen Satz von Konstanten benötigen?

Warum also nicht gleich einen Datenmodellvertrag veröffentlichen? Ich meine, wenn man sie kohärent verwalten und normalisieren kann, warum nicht? ...

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

Jetzt kann ich auf die vertraglich festgelegten Etiketten meiner Anwendungen verweisen, z. B. so

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

Das verwirrt den Inhalt der jar-Datei? Als Java-Programmierer kümmere ich mich nicht um die Struktur der jar-Datei.

Dies macht das osgi-motivierte Laufzeit-Swapping komplex ? Osgi ist ein äußerst effizientes Mittel, um Programmierern die Fortsetzung ihrer schlechten Gewohnheiten zu ermöglichen. Es gibt bessere Alternativen als osgi.

Oder warum nicht so? Es gibt kein Durchsickern der privaten Konstanten in den veröffentlichten Vertrag. Alle privaten Konstanten sollten in einer privaten Schnittstelle mit dem Namen "Konstanten" zusammengefasst werden, denn ich möchte nicht nach Konstanten suchen müssen und bin zu faul, immer wieder "private final String" einzugeben.

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Vielleicht sogar das:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Das einzige Problem, das bei Schnittstellenkonstanten zu beachten ist, ist die Implementierung der Schnittstelle.

Dies ist nicht die "ursprüngliche Absicht" von Schnittstellen? Als ob ich mich für die "ursprüngliche Absicht" der Gründerväter bei der Ausarbeitung der US-Verfassung interessieren würde, anstatt dafür, wie der Oberste Gerichtshof die geschriebenen Buchstaben der US-Verfassung auslegen würde

Schließlich lebe ich im Land der Freien, der Wilden und der Tapferen. Sei mutig, sei frei, sei wild - benutze die Schnittstelle. Wenn meine Programmierer-Kollegen sich weigern, effiziente und faule Mittel der Programmierung zu verwenden, bin ich dann nach der goldenen Regel verpflichtet, meine Programmiereffizienz zu verringern, um mich an ihre anzupassen? Vielleicht sollte ich das tun, aber das ist keine ideale Situation.

0voto

bincob Punkte 839

Ich benutze static final um Konstanten zu deklarieren und die ALL_CAPS-Notation zu verwenden. Ich habe im wirklichen Leben schon einige Fälle gesehen, in denen alle Konstanten in einer Schnittstelle zusammengefasst wurden. In einigen Beiträgen wurde dies zu Recht als schlechte Praxis bezeichnet, vor allem weil eine Schnittstelle nicht dafür gedacht ist. Eine Schnittstelle sollte einen Vertrag erzwingen und nicht ein Ort sein, an dem man unverbundene Konstanten unterbringt. Die Konstante in eine Klasse zu packen, die nicht instanziiert werden kann (durch einen privaten Konstruktor), ist auch in Ordnung, wenn die Semantik der Konstante nicht zu einer bestimmten Klasse oder mehreren Klassen gehört. Ich packe eine Konstante immer in die Klasse, mit der sie am meisten zu tun hat, weil das Sinn macht und außerdem leicht zu pflegen ist.

Enums sind eine gute Wahl, um einen Wertebereich darzustellen, aber wenn Sie eigenständige Konstanten mit Betonung auf dem absoluten Wert speichern (z. B. TIMEOUT = 100 ms), können Sie einfach die Option static final Ansatz.

0voto

wulfgarpro Punkte 6448

static final ist meine Präferenz, ich würde nur eine enum wenn das Element tatsächlich aufzählbar war.

0voto

Javamann Punkte 2844

Einer der Wege, wie ich es tue, ist die Erstellung einer "Global"-Klasse mit den konstanten Werten und ein statischer Import in den Klassen, die Zugriff auf die Konstante benötigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X