Was ist der beste Weg, um Konstanten in Java zu implementieren? [geschlossen]


372

Ich habe Beispiele wie dieses gesehen:

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

und nahm an, dass ich eine Konstantenklasse haben könnte, in die Konstanten eingeschlossen werden könnten, und erklärte sie für statisch endgültig. Ich kenne praktisch kein Java und frage mich, ob dies der beste Weg ist, Konstanten zu erstellen.



Antworten:


403

Das ist durchaus akzeptabel, wahrscheinlich sogar der Standard.

(public/private) static final TYPE NAME = VALUE;

Wo TYPEist der Typ, NAMEist der Name in allen Großbuchstaben mit Unterstrichen für Leerzeichen und VALUEist der konstante Wert;

Ich empfehle dringend, Ihre Konstanten NICHT in ihre eigenen Klassen oder Schnittstellen zu setzen.

Als Randnotiz: Variablen, die als endgültig deklariert und veränderbar sind, können weiterhin geändert werden. Die Variable kann jedoch niemals auf ein anderes Objekt zeigen.

Zum Beispiel:

public static final Point ORIGIN = new Point(0,0);

public static void main(String[] args){

    ORIGIN.x = 3;

}

Das ist legal und ORIGINwäre dann ein Punkt bei (3, 0).


19
Sie können sogar statische MaxSeconds.MAX_SECONDS importieren. damit Sie es nicht buchstabieren müssen MaxSeconds.MAX_SECONDS
Aaron Maenpaa

23
Der vorherige Kommentar zum statischen Import gilt nur für Java 5+. Einige sind der Meinung, dass die Kurzschrift die mögliche Verwirrung darüber, woher die Konstante stammt, nicht wert ist. Beim Lesen von langem Code ist es möglicherweise einfacher, MaxSeconds.MAX_SECONDS zu folgen, als die Importe zu betrachten.
MetroidFan2002

5
Da Sie das Objekt ändern können, wie es jjnguy gezeigt hat, ist es am besten, wenn Ihre Konstanten unveränderliche Objekte oder einfach nur Grundelemente / Zeichenfolgen sind.
Marcospereira

14
Wenn Sie diese Frage lesen, lesen Sie bitte die nächsten beiden Antworten, bevor Sie diese Antwort zu ernst nehmen, obwohl sie akzeptiert wird, ist sie umstritten, wenn nicht falsch.
Orbfish

3
@jjnguy Sie liegen nicht falsch, aber wenn ich nur die Frage und die ersten paar Zeilen Ihrer Antwort lese, hätte ich den Eindruck, dass "eine Konstantenklasse" "vollkommen akzeptabel ist, wahrscheinlich sogar der Standard". Diese Vorstellung ist falsch.
Zach Lysobey

235

Ich würde dringend davon abraten, eine einzige Konstantenklasse zu haben. Es mag zu dieser Zeit eine gute Idee sein, aber wenn Entwickler sich weigern, Konstanten zu dokumentieren, und die Klasse auf über 500 Konstanten anwächst, die alle überhaupt nicht miteinander in Beziehung stehen (da sie sich auf ganz unterschiedliche Aspekte der Anwendung beziehen), ist dies der Fall Im Allgemeinen wird die Konstantendatei vollständig unlesbar. Stattdessen:

  • Wenn Sie Zugriff auf Java 5+ haben, verwenden Sie Aufzählungen, um Ihre spezifischen Konstanten für einen Anwendungsbereich zu definieren. Alle Teile des Anwendungsbereichs sollten sich für diese Konstanten auf Aufzählungen und nicht auf konstante Werte beziehen. Sie können eine Aufzählung deklarieren, die der Deklaration einer Klasse ähnelt. Aufzählungen sind vielleicht die nützlichste (und wohl einzige) Funktion von Java 5+.
  • Wenn Sie Konstanten haben, die nur für eine bestimmte Klasse oder eine ihrer Unterklassen gültig sind, deklarieren Sie sie entweder als geschützt oder als öffentlich und platzieren Sie sie in der obersten Klasse in der Hierarchie. Auf diese Weise können die Unterklassen auf diese Konstantenwerte zugreifen (und wenn andere Klassen über public auf sie zugreifen, sind die Konstanten nicht nur für eine bestimmte Klasse gültig ... was bedeutet, dass die externen Klassen, die diese Konstante verwenden, möglicherweise zu eng an die gekoppelt sind Klasse mit der Konstante)
  • Wenn Sie eine Schnittstelle mit definiertem Verhalten haben, aber zurückgegebene Werte oder Argumentwerte besonders sein sollten, ist es durchaus akzeptabel, Konstanten auf dieser Schnittstelle zu definieren, damit andere Implementierer Zugriff darauf haben. Vermeiden Sie jedoch das Erstellen einer Schnittstelle, die nur Konstanten enthält: Sie kann genauso schlecht werden wie eine Klasse, die nur zum Halten von Konstanten erstellt wurde.

12
stimme voll und ganz zu ... dies kann als klassisches Anti-Muster für große Projekte dokumentiert werden.
Das

30
Off Topic, aber ... Generika sind sicherlich nicht perfekt, aber ich denke, Sie könnten ein ziemlich gutes Argument dafür liefern, dass sie eine nützliche Funktion von Java 5 sind :)
Martin McNulty

3
@ ŁukaszL. Die Frage selbst ist wirklich meinungsbasiert (wann immer "am besten" auftaucht, ist es normalerweise eine Ansichtssache), daher ist die Antwort eine gültige Antwort auf diese Frage. Ich habe eine Antwort gegeben, was (ja, ich glaube es ist, also ja, es ist eine Meinung, weil sich wieder "am besten" mit der Zeit ändert und im Allgemeinen meinungsbasiert ist) der beste Weg ist, Konstanten in Java zu implementieren.
MetroidFan2002

1
Keine der oben genannten Optionen gibt Ihnen eine echte globale Variable. Was ist, wenn ich etwas habe, das überall verwendet wird, aber keine Aufzählung ist? Mache ich nur eine Aufzählung?
Märzhegrea

1
Wenn Sie eine globale Konstante benötigen, die alle Module umfasst, stimmt wahrscheinlich etwas mit Ihrer Entwurfsstrategie nicht. Wenn Sie wirklich eine globale Konstante benötigen, erstellen Sie eine öffentliche Abschlussklasse für diese auf der obersten Ebene und kleben Sie sie dort fest. Löschen Sie es dann, sobald Sie feststellen, dass nicht alle Klassen diese Konstante tatsächlich benötigen, und verschieben Sie es in das Paket, das am häufigsten darauf verweist. Sie können eine Konstante für mehrere Pakete freigeben, aber es ist ein Codegeruch, eine globale Konstante zu benötigen, die kein Aufzählungstyp ist, da Aufzählungstypen Verhalten haben können, aber eine Zeichenfolge eine Zeichenfolge, ein Int ein Int usw. ist.
MetroidFan2002

120

Es ist eine SCHLECHTE PRAXIS , Schnittstellen nur zum Halten von Konstanten zu verwenden ( von Josh Bloch als konstantes Schnittstellenmuster bezeichnet ). Hier ist, was Josh rät:

Wenn die Konstanten stark an eine vorhandene Klasse oder Schnittstelle gebunden sind, sollten Sie sie der Klasse oder Schnittstelle hinzufügen. Beispielsweise exportieren alle umrahmten numerischen Grundklassen wie Integer und Double die Konstanten MIN_VALUE und MAX_VALUE. Wenn die Konstanten am besten als Elemente eines Aufzählungstyps angezeigt werden, sollten Sie sie mit einem Aufzählungstyp exportieren . Andernfalls sollten Sie die Konstanten mit einer nicht instabilisierbaren Dienstprogrammklasse exportieren.

Beispiel:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

Über die Namenskonvention:

Konventionell haben solche Felder Namen, die aus Großbuchstaben bestehen, wobei Wörter durch Unterstriche getrennt sind. Es ist wichtig, dass diese Felder entweder primitive Werte oder Verweise auf unveränderliche Objekte enthalten.


23
Wenn Sie etwas Schlechtes nennen wollen, sollten Sie vielleicht erklären, warum Sie denken, dass es so ist?
GlennS

14
Dies ist ein alter Beitrag, aber es ist besser, die abstractNotation für die Klasse anstelle des privaten Konstruktors zu verwenden.
Xtreme Biker

5
Matt, obwohl die Empfehlung des Bikers nicht falsch ist, würde ich mich eher für Abschlussklassen als für abstrakte Klassen einsetzen. Biker meinte damit, dass Sie sicherstellen möchten, dass Ihre Konstantenklasse nicht geändert werden kann. Wenn Sie es als endgültig markieren, können Sie nicht zulassen, dass es in Unterklassen unterteilt oder instanziiert wird. Dies hilft auch dabei, die statische Funktionalität zu kapseln, und erlaubt anderen Entwicklern nicht, sie in Unterklassen zu unterteilen und sie dazu zu bringen, Dinge zu tun, für die sie nicht entwickelt wurden.
Liltitus27

7
@XtremeBiker Das Markieren der Klasse abstractanstelle eines privaten Konstruktors verhindert die Instanziierung nicht vollständig, da man sie unterklassifizieren und die Unterklasse instanziieren könnte (nicht, dass dies eine gute Idee ist, aber möglich). @ToolmakerSteve Sie können eine Klasse nicht mit einem privaten Konstruktor unterordnen (zumindest nicht ohne einen großen schlechten Hack), da der Konstruktor der Unterklasse den (jetzt privaten) Konstruktor seiner Oberklasse aufrufen muss. Das Markieren finalist also unnötig (aber vielleicht expliziter).
Importieren Sie diesen

3
Es ist noch schlimmer, Klasse nur zum Halten von Konstanten zu verwenden. Wenn Sie niemals ein Objekt dieser Klasse erstellen möchten, warum verwenden Sie dann überhaupt die reguläre Klasse ?
MaxZoom

36

In Effective Java (2. Ausgabe) wird empfohlen, Enums anstelle von statischen Ints für Konstanten zu verwenden.

Hier finden Sie eine gute Beschreibung der Aufzählungen in Java: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

Beachten Sie, dass am Ende dieses Artikels folgende Frage gestellt wird:

Wann sollten Sie also Aufzählungen verwenden?

Mit einer Antwort von:

Jedes Mal, wenn Sie einen festen Satz von Konstanten benötigen


21

Vermeiden Sie einfach die Verwendung einer Schnittstelle:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

Es ist verlockend, verletzt jedoch die Kapselung und verwischt die Unterscheidung von Klassendefinitionen.


1
In der Tat sind statische Importe weitaus vorzuziehen.
Aaron Maenpaa

1
Diese Vorgehensweise ist eine seltsame Verwendung von Schnittstellen, mit denen die von einer Klasse bereitgestellten Dienste angegeben werden sollen.
Rafa Romero

1
Ich bin nicht anderer Meinung, die Verwendung der Schnittstelle für Konstanten zu vermeiden, aber Ihr Beispiel ist meiner Meinung nach irreführend. Sie müssen die Schnittstelle nicht implementieren, um Zugriff auf die Konstante zu erhalten, da diese implizit statisch, öffentlich und endgültig ist. Es ist also einfacher als Sie hier beschrieben haben.
Djangofan

Das ist wahr ... es verstößt gegen die Kapselung. Ich bevorzuge die Verwendung der endgültigen Konstantenklasse, die objektorientierter aussieht und der Schnittstelle ODER Aufzählung vorzuziehen ist . Hinweis: Enum kann vermieden werden , wenn Android nicht benötigt wird.
CoDe

19

Ich benutze folgenden Ansatz:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Dann benutze ich zum Beispiel, Constants.DB.Connection.URLum konstant zu werden. Es sieht für mich eher "objektorientiert" aus.


4
Interessant, aber umständlich. Warum würden Sie nicht stattdessen Konstanten in der Klasse erstellen, die am engsten mit ihnen verbunden ist, wie von anderen empfohlen? Haben Sie beispielsweise in Ihrem DB-Code an anderer Stelle eine Basisklasse für Ihre Verbindungen? ZB "ConnectionBase". Dann können Sie die Konstanten dort setzen. Jeder Code, der mit Verbindungen arbeitet, hat wahrscheinlich bereits einen Import, der einfach "ConnectionBase.URL" anstelle von "Constants.DB.Connection.URL" sagen kann.
ToolmakerSteve

3
@ToolmakerSteve Aber was ist mit allgemeinen Konstanten, die mehrere Klassen verwenden können? Zum Beispiel Stile, URLs von Webdiensten usw.?
Daniel Gomez Rico

Das Einfügen aller Konstanten in eine Klasse hat einen Vorteil - die Wartung. Sie wissen immer genau, wo Sie die Konstanten finden. Ich sage nicht, dass dies diese Technik besser macht, ich biete nur einen Vorteil. Und was @ albus.ua getan hat, ist die Kategorisierung seiner Konstanten, was eine ziemlich gute Idee ist, insbesondere wenn die Konstantenklasse viele, viele konstante Werte enthält. Diese Technik hilft, die Klasse überschaubar zu halten und den Zweck der Konstante besser zu beschreiben.
Nelda.techspiress

17

Das Erstellen statischer Endkonstanten in einer separaten Klasse kann zu Problemen führen. Der Java-Compiler optimiert dies tatsächlich und platziert den tatsächlichen Wert der Konstante in einer Klasse, die darauf verweist.

Wenn Sie später die Klasse 'Konstanten' ändern und andere Klassen, die auf diese Klasse verweisen, nicht erneut hart kompilieren, wird eine Kombination aus alten und neuen Werten verwendet.

Anstatt diese als Konstanten zu betrachten, stellen Sie sie sich als Konfigurationsparameter vor und erstellen Sie eine Klasse, um sie zu verwalten. Lassen Sie die Werte nicht endgültig sein und ziehen Sie sogar die Verwendung von Gettern in Betracht. Wenn Sie in Zukunft festlegen, dass einige dieser Parameter tatsächlich vom Benutzer oder Administrator konfiguriert werden können, ist dies viel einfacher.


+1 für diese hervorragende Einschränkung. (Wenn Sie nicht garantieren können, dass es sich um eine permanente Konstante handelt, ziehen Sie stattdessen einen Getter in Betracht, wie big_peanut_horse erwähnt.) Dasselbe gilt übrigens für const in C #: msdn.microsoft.com/en-us/library/e6w8fe1b.aspx
Jon Coombs

13

Der größte Fehler, den Sie machen können, ist das Erstellen einer global zugänglichen Klasse mit einem generischen Namen wie Konstanten. Dies wird einfach mit Müll übersät und Sie verlieren alle Fähigkeit herauszufinden, welcher Teil Ihres Systems diese Konstanten verwendet.

Stattdessen sollten Konstanten in die Klasse gehen, die sie "besitzt". Haben Sie eine Konstante namens TIMEOUT? Es sollte wahrscheinlich in Ihre Communications () - oder Connection () -Klasse aufgenommen werden. MAX_BAD_LOGINS_PER_HOUR? Geht in User (). Und so weiter und so fort.

Die andere mögliche Verwendung sind Java .properties-Dateien, wenn "Konstanten" zur Laufzeit definiert werden können, aber nicht einfach vom Benutzer geändert werden können. Sie können diese in Ihre .jars packen und mit dem Class resourceLoader referenzieren.


Und natürlich möchten Sie niemals auf eine Konstante aus mehr als einer Klasse zugreifen oder Unordnung an der Spitze einer Klasse vermeiden.
Orbfish

6

Das ist der richtige Weg.

Im Allgemeinen werden Konstanten nicht in separaten "Konstanten" -Klassen aufbewahrt, da sie nicht erkennbar sind. Wenn die Konstante für die aktuelle Klasse relevant ist, hilft es dem nächsten Entwickler, sie dort zu belassen.



5

Ich benutze lieber Getter als Konstanten. Diese Getter können konstante Werte zurückgeben, zpublic int getMaxConnections() {return 10;} alles, was die Konstante benötigt, durchläuft einen Getter.

Ein Vorteil ist, dass Sie, wenn Ihr Programm über die Konstante hinauswächst - Sie finden, dass es konfigurierbar sein muss - einfach ändern können, wie der Getter die Konstante zurückgibt.

Der andere Vorteil ist, dass Sie zum Ändern der Konstante nicht alles neu kompilieren müssen, was sie verwendet. Wenn Sie auf ein statisches Endfeld verweisen, wird der Wert dieser Konstante in einen beliebigen Bytecode kompiliert, der darauf verweist.


5
Das erneute Kompilieren von Referenzierungsklassen ist im 21. Jahrhundert kaum eine Belastung. Und Sie sollten das Accessor / Mutator-Modell (Getter / Setter) niemals für andere Zwecke als den Zugriff auf und die Mutation von Mitgliedsvariablen verwenden. Konstanten sollen konzeptionell von Natur aus unmittelbar sein, während Getter / Setter (beide) den Zustand verwalten sollen . Außerdem bitten Sie nur um Verwirrung: Die Leute erwarten nicht, dass ein Getter eine bloße Konstante liefert.

5

Ich bin damit einverstanden, dass die Verwendung einer Schnittstelle nicht der richtige Weg ist. Das Vermeiden dieses Musters hat sogar einen eigenen Gegenstand (# 18) in Blochs effektivem Java .

Ein Argument, das Bloch gegen das konstante Schnittstellenmuster vorbringt, ist, dass die Verwendung von Konstanten ein Implementierungsdetail ist, aber die Implementierung einer Schnittstelle, um sie zu verwenden, macht dieses Implementierungsdetail in Ihrer exportierten API verfügbar.

Das public|private static final TYPE NAME = VALUE; Muster ist eine gute Möglichkeit, eine Konstante zu deklarieren. Persönlich denke ich, dass es besser ist, eine separate Klasse zu erstellen, um alle Ihre Konstanten aufzunehmen, aber ich habe nie einen Grund gesehen, dies nicht zu tun, außer persönlichen Vorlieben und Stil.

Wenn Ihre Konstanten als Aufzählung gut modelliert werden können, berücksichtigen Sie die Aufzählung - Struktur in 1.5 oder höher.

Wenn Sie eine frühere Version als 1.5 verwenden, können Sie weiterhin typsichere Aufzählungen mithilfe normaler Java-Klassen abrufen. (Weitere Informationen hierzu finden Sie auf dieser Website .)


Einige Konstanten können zum Aufrufen einer API verwendet werden. Siehe beispielsweise die Schnittstelle org.springframework.transaction.TransactionDefinition. Es hat eine Liste von Konstanten wie int PROPAGATION_REQUIRED = 0;
Borjab

Ich weiß, dass dies alt ist, aber die Verbindung zu Blochs effektivem Java ist unterbrochen. Könnten Sie bitte eine andere oder eine andere Referenz angeben, die unterstützt, dass "die Verwendung einer Schnittstelle nicht der richtige Weg ist"?
Nelda.techspiress

4

Basierend auf den obigen Kommentaren denke ich, dass dies ein guter Ansatz ist, um die altmodische globale Konstantenklasse (mit öffentlichen statischen Endvariablen) auf folgende Weise in ihr enumartiges Äquivalent zu ändern:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_HOST("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Dann kann ich sie auf Folgendes verweisen:

Constants.StringConstant.DB_HOST

4
Warum? Wie ist das eine Verbesserung? Jede Referenz ist jetzt umständlich (Constants.StringConstant.whatever). IMHO, Sie gehen hier eine holprige Straße hinunter.
ToolmakerSteve

3

Ein gutes objektorientiertes Design sollte nicht viele öffentlich verfügbare Konstanten benötigen. Die meisten Konstanten sollten in der Klasse gekapselt sein, die sie für ihre Arbeit benötigt.


1
Oder über den Konstruktor in diese Klasse eingefügt.
WW.

2

Es gibt eine gewisse Meinung, um dies zu beantworten. Zunächst werden Konstanten in Java im Allgemeinen als öffentlich, statisch und endgültig deklariert. Nachfolgend sind die Gründe aufgeführt:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Ich würde niemals eine Schnittstelle für einen CONSTANTS-Accessor / ein CONSTANTS-Objekt verwenden, nur weil allgemein erwartet wird, dass Schnittstellen implementiert werden. Würde das nicht lustig aussehen:

String myConstant = IMyInterface.CONSTANTX;

Stattdessen würde ich zwischen einigen verschiedenen Möglichkeiten wählen, basierend auf einigen kleinen Kompromissen, und daher hängt es davon ab, was Sie brauchen:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe

2

Was ist der beste Weg, um Konstanten in Java zu implementieren?

Ein Ansatz, den wir wirklich vermeiden sollten : Verwenden von Schnittstellen zum Definieren von Konstanten.

Das Erstellen einer Schnittstelle speziell zum Deklarieren von Konstanten ist wirklich das Schlimmste: Sie beseitigt den Grund, warum Schnittstellen entworfen wurden: das Definieren von Methodenverträgen.

Selbst wenn bereits eine Schnittstelle vorhanden ist, um einen bestimmten Bedarf zu decken, ist die Deklaration der darin enthaltenen Konstanten nicht sinnvoll, da Konstanten nicht Teil der API und des Vertrags sein sollten, der für Clientklassen bereitgestellt wird.


Zur Vereinfachung haben wir im Allgemeinen 4 gültige Ansätze .

Mit static final String/IntegerFeld:

  • 1) Verwenden einer Klasse, die Konstanten innerhalb deklariert, aber nicht nur.
  • 1 Variante) Erstellen einer Klasse, die nur Konstanten deklariert.

Mit Java 5 enum:

  • 2) Deklarieren der Aufzählung in einer verwandten Zweckklasse (also als verschachtelte Klasse).
  • 2 Variante) Erstellen der Aufzählung als eigenständige Klasse (so definiert in einer eigenen Klassendatei).

TLDR: Was ist der beste Weg und wo finden Sie die Konstanten?

In den meisten Fällen ist der Aufzählungsweg wahrscheinlich feiner als der static final String/IntegerWeg, und ich persönlich denke, dass der static final String/IntegerWeg nur verwendet werden sollte, wenn wir gute Gründe haben, keine Aufzählungen zu verwenden.
Und wo wir die konstanten Werte deklarieren sollen, ist die Idee zu suchen, ob es eine einzelne existierende Klasse gibt, die einen spezifischen und starken funktionalen Zusammenhalt mit konstanten Werten besitzt. Wenn wir eine solche Klasse finden, sollten wir sie als Konstantenhalter verwenden . Andernfalls sollte die Konstante keiner bestimmten Klasse zugeordnet werden.


static final String/ static final Integerversusenum

Die Verwendung von Enums ist wirklich ein Weg, um stark in Betracht gezogen zu werden.
Aufzählungen haben einen großen Vorteil gegenüber Stringoder Integerkonstanten Bereich.
Sie legen eine stärkere Kompilierungsbeschränkung fest. Wenn Sie eine Methode definieren, die die Aufzählung als Parameter verwendet, können Sie nur einen Aufzählungswert übergeben, der in der Aufzählungsklasse (oder null) definiert ist.
Mit String und Integer können Sie sie durch beliebige Werte kompatiblen Typs ersetzen. Die Kompilierung ist auch dann in Ordnung, wenn der Wert keine definierte Konstante in den Feldern static final String/ static final Integerist.

Beispiel: Unten zwei Konstanten, die in einer Klasse als static final StringFelder definiert sind:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

Hier eine Methode, die erwartet, eine dieser Konstanten als Parameter zu haben:

public void process(String constantExpected){
    ...    
}

Sie können es folgendermaßen aufrufen:

process(MyClass.ONE_CONSTANT);

oder

process(MyClass.ANOTHER_CONSTANT);

Keine Kompilierungsbeschränkung hindert Sie jedoch daran, sie auf folgende Weise aufzurufen:

process("a not defined constant value");

Sie würden den Fehler nur zur Laufzeit haben und nur, wenn Sie zu einem Zeitpunkt eine Überprüfung des übertragenen Werts durchführen.

Bei enum sind keine Überprüfungen erforderlich, da der Client nur einen enum-Wert in einem enum-Parameter übergeben konnte.

Zum Beispiel hier zwei Werte, die in einer Enum-Klasse definiert sind (also sofort einsatzbereit):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

Hier eine Methode, die einen dieser Enum-Werte als Parameter erwartet:

public void process(MyEnum myEnum){
    ...    
}

Sie können es folgendermaßen aufrufen:

process(MyEnum.ONE_CONSTANT);

oder

process(MyEnum.ANOTHER_CONSTANT);

Die Zusammenstellung wird es Ihnen jedoch niemals erlauben, sie auf diese Weise aufzurufen:

process("a not defined constant value");

Wo sollen wir die Konstanten deklarieren?

Wenn Ihre Anwendung eine einzelne vorhandene Klasse enthält, die eine spezifische und starke funktionale Kohäsion mit den konstanten Werten besitzt, erscheinen 1) und 2) intuitiver.
Im Allgemeinen wird die Verwendung der Konstanten vereinfacht, wenn diese in der Hauptklasse deklariert sind, die sie manipuliert, oder deren Name sehr natürlich ist, um zu erraten, dass wir ihn darin finden werden.

In der JDK-Bibliothek werden beispielsweise die Exponential- und Pi-Konstantenwerte in einer Klasse deklariert, die nicht nur Konstantendeklarationen deklariert ( java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

Die Clients, die mathematische Funktionen verwenden, verlassen sich häufig auf die MathKlasse. So können sie Konstanten leicht genug finden und sich auch daran erinnern, wo Eund PIauf sehr natürliche Weise definiert sind.

Wenn Ihre Anwendung keine vorhandene Klasse enthält, die eine sehr spezifische und starke funktionale Kohäsion mit den konstanten Werten aufweist, erscheinen die Methoden 1 Variante) und 2 Variante intuitiver.
Im Allgemeinen erleichtert es die Verwendung der Konstanten nicht, wenn diese in einer Klasse deklariert werden, die sie manipuliert, während wir auch 3 oder 4 andere Klassen haben, die sie so oft manipulieren, und keine dieser Klassen scheint natürlicher zu sein als andere Hostkonstantenwerte.
Hier ist es sinnvoll, eine benutzerdefinierte Klasse zu definieren, die nur konstante Werte enthält.
In der JDK-Bibliothek wird die java.util.concurrent.TimeUnitAufzählung beispielsweise nicht in einer bestimmten Klasse deklariert, da es nicht wirklich nur eine JDK-spezifische Klasse gibt, die als die intuitivste erscheint, um sie zu speichern:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Viele Klassen deklariert in java.util.concurrentGebrauch ihnen: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... und wirklich niemand von ihnen besser geeignet scheint , die Enum zu halten.


1

Eine Konstante eines beliebigen Typs kann deklariert werden, indem eine unveränderliche Eigenschaft innerhalb einer Klasse erstellt wird (dh eine Mitgliedsvariable mit dem finalModifikator). Typischerweise werden auch die Modifikatoren staticund publicbereitgestellt.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

Es gibt zahlreiche Anwendungen, bei denen der Wert einer Konstante eine Auswahl aus einem n-Tupel (z. B. Aufzählung ) von Auswahlmöglichkeiten anzeigt . In unserem Beispiel können wir einen Aufzählungstyp definieren, der die möglichen zugewiesenen Werte einschränkt (dh die verbesserte Typensicherheit ):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}

1

Eine einzelne generische Konstantenklasse ist eine schlechte Idee. Konstanten sollten zusammen mit der Klasse gruppiert werden, mit der sie am logischsten verwandt sind.

Anstatt Variablen jeglicher Art (insbesondere Aufzählungen) zu verwenden, würde ich vorschlagen, dass Sie Methoden verwenden. Erstellen Sie eine Methode mit demselben Namen wie die Variable und lassen Sie sie den Wert zurückgeben, den Sie der Variablen zugewiesen haben. Löschen Sie nun die Variable und ersetzen Sie alle Verweise darauf durch Aufrufe der gerade erstellten Methode. Wenn Sie der Meinung sind, dass die Konstante generisch genug ist, dass Sie keine Instanz der Klasse erstellen müssen, um sie zu verwenden, machen Sie die Konstantenmethode zu einer Klassenmethode.


1

FWIW, ein Zeitlimit in Sekunden sollte wahrscheinlich eine Konfigurationseinstellung (aus einer Eigenschaftendatei oder durch Injektion wie im Frühjahr eingelesen) und keine Konstante sein.


1

Was ist der Unterschied

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

und verwenden, MyGlobalConstants.TIMEOUT_IN_SECSwo immer wir diese Konstante brauchen. Ich denke beide sind gleich.


1
Dies scheint im Wesentlichen ein Kommentar als Antwort auf die Antwort von bincob zu sein. Ich denke, sie verhalten sich sehr ähnlich, aber der Punkt von bincob war, dass sie in keiner Weise eine Schnittstelle definieren. Der Vorschlag bestand darin, realen Klassen Konstanten hinzuzufügen und keine MyGlobalConstants-Skelettklasse zu erstellen. (Obwohl dies gelegentlich sinnvoll ist; verwenden Sie eine "statische Klasse", indem Sie statische Konstanten und einen privaten Konstruktor verwenden, um eine Instanziierung zu verhindern; siehe java.lang.math.) Erwägen Sie die Verwendung von enum.
Jon Coombs

Wenn Sie auch "final" in die Klassendeklaration einfügen, wird eine Unterklasse verhindert. (In C # können Sie "statisch" ausführen, was "endgültige Zusammenfassung" bedeutet, sodass kein expliziter privater Konstruktor erforderlich ist.)
Jon Coombs

Ja, @JonCoombs, aber "final" verhindert nicht die direkte Instanziierung. Und Java verbietet, dass sowohl final als auch abstract für Klassen zusammen angezeigt werden, daher der endlos erscheinende private Konstruktor, um sowohl Instanziierung als auch Unterklassen zu verhindern. Ich habe keine Ahnung, warum "final abstract" nicht erlaubt ist, außer dass es auf den ersten Blick widersprüchlich erscheint, wenn es lautet: "Sie können nicht unterklassifizieren, aber diese Klasse soll unterklassifiziert werden".

0

Ich würde die Klasse nicht (abgesehen vom Gehäuse) als die Konstante bezeichnen ... Ich hätte mindestens eine Klasse von "Einstellungen" oder "Werten" oder "Konstanten", in der alle Konstanten leben würden. Wenn ich eine große Anzahl von ihnen habe, würde ich sie in logische Konstantenklassen (UserSettings, AppSettings usw.) gruppieren.


Eine Klasse namens Konstanten zu haben war das, was ich vorhatte, das war nur ein kleines Beispiel, das ich gefunden habe.
mk.

0

Um noch einen Schritt weiter zu gehen, können Sie global verwendete Konstanten in einer Schnittstelle platzieren, damit sie systemweit verwendet werden können. Z.B

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

Aber dann nicht umsetzen. Verweisen Sie einfach direkt im Code über den vollständig qualifizierten Klassennamen auf sie.


Der Punkt, wenn Sie sie in einer Schnittstelle deklarieren (und nicht implementieren), ist, dass Sie das "öffentliche statische Finale" verpassen können.
Tom Hawtin - Tackline

9
Schnittstellen dienen zur Definition eines Verhaltensvertrags und nicht als Bequemlichkeitsmechanismus zum Halten von Konstanten.
John Topley

@ JohnTopley Ja, aber es funktioniert. ;)
trusktr

0

Für Konstanten ist Enum meiner Meinung nach die bessere Wahl. Hier ist ein Beispiel

öffentliche Klasse myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}

0

Eine Möglichkeit besteht darin, eine 'globale' Klasse mit den konstanten Werten zu erstellen und einen statischen Import in die Klassen durchzuführen, die Zugriff auf die Konstante benötigen.


0

static finalist meine Präferenz, ich würde nur eine verwenden, enumwenn der Artikel tatsächlich aufzählbar wäre.


0

ich benutze static final deklariere Konstanten und gehe mit der Namensnotation ALL_CAPS. Ich habe einige reale Fälle gesehen, in denen alle Konstanten zu einer Schnittstelle zusammengefasst sind. Einige Beiträge haben dies zu Recht als schlechte Praxis bezeichnet, vor allem, weil dies nicht der Zweck einer Benutzeroberfläche ist. Eine Schnittstelle sollte einen Vertrag erzwingen und kein Ort sein, an dem nicht verwandte Konstanten eingefügt werden können. Das Zusammenfügen zu einer Klasse, die nicht instanziiert werden kann (über einen privaten Konstruktor), ist in Ordnung, wenn die konstante Semantik nicht zu einer bestimmten Klasse gehört ( es). Ich habe immer eine Konstante in die Klasse eingefügt, mit der es am meisten zu tun hat, weil das Sinn macht und auch leicht zu warten ist.

Aufzählungen sind eine gute Wahl, um einen Wertebereich darzustellen. Wenn Sie jedoch eigenständige Konstanten mit Schwerpunkt auf dem absoluten Wert speichern (z. B. TIMEOUT = 100 ms), können Sie einfach den static finalAnsatz wählen .


0

Ich stimme dem zu, was die meisten sagen. Es ist am besten, Aufzählungen zu verwenden, wenn es um eine Sammlung von Konstanten geht. Wenn Sie jedoch in Android programmieren, gibt es eine bessere Lösung: IntDef Annotation .

@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 Enums auf einfache Weise überlegen. Sie benötigt deutlich weniger Platz, da sie lediglich eine Markierung zur Kompilierungszeit darstellt. Es ist weder eine Klasse noch verfügt es über die Eigenschaft zur automatischen Konvertierung von Zeichenfolgen.


Ich stimme zwar der bewährten Methode zu, die Benutzeroberfläche nicht nur in Java zu verwenden und Enum in Android zu vermeiden, aber dieser Ersatz in Android funktioniert nur, wenn Sie eine kleine Anzahl von Feldern verwenden. Dies ist eine erhebliche Speicherersparnis, kann jedoch zu Aufblähungen führen, da Sie eine Schnittstelle pro Feld in einer gemischten Aufzählung sind. Wenn ich beispielsweise eine gemischte Aufzählung habe, die definiert, was ein Objekt in seinem Konstruktor nimmt, kann ich mit diesem Ansatz nichts speichern und kehre zu nicht typsicheren Konstanten zurück, da Sie in Android nicht zu viele Klassen / Schnittstellen benötigen.
Droid Teahouse

0

Es ist eine schlechte Angewohnheit und eine schrecklich ärgerliche Praxis , Joshua Bloch zu zitieren, ohne den grundlegenden Ground-Zero-Fundamentalismus zu verstehen.

Ich habe auch nichts von Joshua Bloch gelesen

  • Er ist ein schrecklicher Programmierer
  • oder die Leute, die ihn bisher zitieren (Joshua ist der Name eines Jungen, den ich vermute), verwenden sein Material einfach als religiöse Skripte, um ihre Software-religiösen Ablässe zu rechtfertigen.

Wie im biblischen Fundamentalismus können alle biblischen Gesetze durch zusammengefasst werden

  • Liebe die fundamentale Identität von ganzem Herzen und von ganzem Verstand
  • Liebe deinen Nächsten wie dich

In ähnlicher Weise kann der Fundamentalismus der Softwareentwicklung durch zusammengefasst werden

  • widmen Sie sich mit all Ihrer Programmierkraft und Ihrem Verstand den Ground-Zero-Grundlagen
  • und widmen Sie sich der Exzellenz Ihrer Programmierkollegen, wie Sie es für sich selbst tun würden.

Auch unter biblisch-fundamentalistischen Kreisen wird eine starke und vernünftige Folgerung gezogen

  • Liebe dich zuerst. Denn wenn Sie sich nicht sehr lieben, hat das Konzept "Lieben Sie Ihren Nächsten wie sich selbst" nicht viel Gewicht, da "Wie sehr Sie sich selbst lieben" die Bezugslinie ist, über der Sie andere lieben würden.

Wenn Sie sich als Programmierer nicht respektieren und nur die Aussagen und Prophezeiungen eines Programmier-Guru-nath akzeptieren, ohne die Grundlagen in Frage zu stellen, sind Ihre Zitate und Ihr Vertrauen in Joshua Bloch (und dergleichen) bedeutungslos. Und deshalb hätten Sie eigentlich keinen Respekt vor Ihren Programmierkollegen.

Die Grundgesetze der Softwareprogrammierung

  • Faulheit ist die Tugend eines guten Programmierers
  • Sie sollen Ihr Programmierleben so einfach, faul und damit so effektiv wie möglich gestalten
  • Sie sollen die Konsequenzen und Eingeweide Ihrer Programmierung für Ihre Nachbarprogrammierer, die mit Ihnen zusammenarbeiten und Ihre Programmier-Eingeweide aufgreifen, so einfach, faul und daher so effektiv wie möglich gestalten.

Schnittstellenmusterkonstanten sind eine schlechte Angewohnheit ???

Unter welche Gesetze der grundlegend wirksamen und verantwortungsvollen Programmierung fällt dieses religiöse Edikt?

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

  • Whatif-No IDE? Wer um alles in der Welt würde als Softwareprogrammierer keine IDE verwenden? Die meisten von uns sind Programmierer, die es vorziehen, nicht beweisen zu müssen, dass sie einen macho-aescetischen Überlebenskampf haben, indem sie die Verwendung einer IDE vermeiden.

    • Warten Sie auch einen zweiten Befürworter der mikrofunktionalen Programmierung ab, um keine IDE zu benötigen. Warten Sie, bis Sie meine Erklärung zur Normalisierung des Datenmodells gelesen haben.
  • Verschmutzt den Namespace mit Variablen, die im aktuellen Bereich nicht verwendet werden? Es könnten Befürworter dieser Meinung sein

    • sind sich der Normalisierung des Datenmodells nicht bewusst und sind nicht erforderlich
  • Die Verwendung von Schnittstellen zum Erzwingen von Konstanten ist ein Missbrauch von Schnittstellen. Befürworter solcher haben eine schlechte Angewohnheit von

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

    • Warum sollten Sie sich auf ein Programmiermuster wie Ihren dauerhaften Lebensunterhalt einlassen wollen? IOW, warum widmen Sie sich solch einer AMBIVALENTEN und schlechten Programmiergewohnheit?

Was auch immer die Ausreden sein mögen, es gibt KEINE GÜLTIGE Entschuldigung, wenn es darum geht, die Verwendung von Schnittstellenkonstanten zu delegitimieren oder generell zu entmutigen.

Es spielt keine Rolle, wie die ursprünglichen Absichten und mentalen Zustände der Gründerväter waren, die die Verfassung der Vereinigten Staaten ausgearbeitet haben. Wir könnten die ursprünglichen Absichten der Gründerväter diskutieren, aber alles, was mich interessiert, sind die schriftlichen Erklärungen der US-Verfassung. Und es liegt in der Verantwortung jedes US-Bürgers, den schriftlichen literarischen Fundamentalismus und nicht die ungeschriebenen Gründungsabsichten der US-Verfassung auszunutzen.

Ebenso ist es mir egal, was die "ursprünglichen" Absichten der Gründer der Java-Plattform und der Programmiersprache für die Schnittstelle hatten. 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 einer verantwortungsvollen Softwareprogrammierung zu erfüllen. Es ist mir egal, ob ich als "Verstoß gegen die Absicht für Schnittstellen" wahrgenommen werde. Es ist mir egal, was Gosling oder jemand Bloch über die "richtige Art und Weise, Java zu verwenden" sagt, es sei denn, was sie sagen, verstößt nicht gegen mein Bedürfnis nach EFFEKTIVEN Grundlagen.

Das Fundament ist die Normalisierung von Datenmodellen

Es spielt keine Rolle, wie Ihr Datenmodell gehostet oder übertragen wird. Unabhängig davon, ob Sie Schnittstellen oder Aufzählungen oder Whatevernots verwenden, relational oder ohne SQL, wenn Sie die Notwendigkeit und den Prozess der Normalisierung von Datenmodellen nicht verstehen.

Wir müssen zuerst 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 Funktionsverhalten zu definieren und einen Bereich oder einen Bereich von Anwendungen zu blockieren. Und nur dann können wir die API jedes Funktionsprozesses definieren.

Sogar die von EF Codd vorgeschlagenen Facetten der Datennormalisierung sind jetzt stark in Frage gestellt und in Frage gestellt. zB wurde seine Aussage zu 1NF als mehrdeutig, falsch ausgerichtet und zu stark vereinfacht kritisiert, ebenso wie der Rest seiner Aussagen, insbesondere zum Aufkommen moderner Datendienste, Repo-Technologie und Übertragung. IMO sollten die EF Codd-Anweisungen vollständig verworfen und neue mathematisch plausibelere Anweisungen entworfen werden.

Ein eklatanter Fehler von EF Codd und die Ursache für seine Fehlausrichtung auf ein effektives menschliches Verständnis ist seine Überzeugung, dass vom Menschen wahrnehmbare mehrdimensionale Daten mit veränderlichen Dimensionen durch eine Reihe von stückweisen zweidimensionalen Abbildungen effizient wahrgenommen werden können.

Die Grundlagen der Datennormalisierung

Was EF Codd nicht ausdrücken konnte.

Innerhalb jedes kohärenten Datenmodells ist dies die sequentielle abgestufte Reihenfolge der zu erreichenden Datenmodellkohärenz.

  1. Die Einheit und Identität von Dateninstanzen.
    • Entwerfen Sie die Granularität jeder Datenkomponente, wobei ihre Granularität auf einer Ebene liegt, auf der jede Instanz einer Komponente eindeutig identifiziert und abgerufen werden kann.
    • Fehlen eines Instanz-Aliasing. dh es gibt keine Mittel, mit denen eine Identifikation mehr als eine Instanz einer Komponente erzeugt.
  2. Fehlen eines Instanz-Übersprechens. 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-De-Aliasing. Es muss eine Definition existieren, mit der eine Komponente / Dimension eindeutig identifiziert werden kann. Welches ist die primäre Definition einer Komponente;
    • wenn die primäre Definition nicht dazu führt, dass Unterdimensionen oder Elementkomponenten verfügbar gemacht werden, die nicht Teil einer beabsichtigten Komponente sind;
  4. Einzigartige Mittel zum Dealiasing von Komponenten. Es muss eine und nur eine solche De-Aliasing-Definition für eine Komponente 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 Gruppe von Mitgliedskomponenten eines Kindes abhängen. Eine Mitgliedskomponente der Identität eines Elternteils muss die vollständige Kinderidentität sein, ohne auf einige oder alle Kinder eines Kindes zu verweisen.
  7. Vermeiden Sie bimodale oder multimodale Erscheinungen eines Datenmodells.
    • Wenn zwei Kandidatendefinitionen einer Komponente vorhanden sind, ist dies ein offensichtliches Zeichen dafür, dass zwei verschiedene Datenmodelle als eines verwechselt werden. Das heißt, es gibt Inkohärenz auf Datenmodellebene oder auf Feldebene.
    • Ein Anwendungsbereich muss kohärent ein und nur ein Datenmodell verwenden.
  8. Komponentenmutation erkennen und identifizieren. Wenn Sie keine statistische Komponentenanalyse großer Datenmengen durchgeführt haben, sehen Sie wahrscheinlich keine Komponentenmutation oder sehen die Notwendigkeit, diese zu behandeln.
    • Bei einem Datenmodell können einige seiner Komponenten zyklisch oder allmählich mutieren.
    • Der Modus kann Elementdrehung oder Transpositionsdrehung sein.
    • Eine Mutation der Mitgliederrotation könnte ein deutlicher Austausch von untergeordneten Komponenten zwischen Komponenten sein. Oder wo völlig neue Komponenten definiert werden müssten.
    • Eine transpositionelle Mutation würde sich als ein Dimensionselement manifestieren, das zu einem Attribut mutiert, und umgekehrt.
    • Jeder Mutationszyklus muss als eigenständiges Datenmodal identifiziert werden.
  9. Versioniere jede Mutation. So können Sie eine frühere Version des Datenmodells herausziehen, wenn möglicherweise die Notwendigkeit besteht, eine 8 Jahre alte Mutation des Datenmodells zu behandeln.

In einem Bereich oder Raster von Komponentenanwendungen zwischen Serviceleistungen muss es nur ein einziges kohärentes Datenmodell geben oder es gibt ein Mittel, mit dem sich ein Datenmodell / eine Version identifizieren kann.

Fragen wir uns immer noch, ob wir Schnittstellenkonstanten verwenden könnten? Ja wirklich ?

Es geht um Probleme bei der Datennormalisierung, die konsequenter sind als diese weltliche Frage. Wenn Sie diese Probleme nicht lösen, ist die Verwirrung, die Schnittstellenkonstanten Ihrer Meinung nach verursachen, vergleichsweise gering. Zilch.

Aus der Normalisierung des Datenmodells bestimmen Sie dann die Komponenten als Variablen, als Eigenschaften, als Vertragsschnittstellenkonstanten.

Anschließend bestimmen Sie, welche Werte in die Wertinjektion, die Platzhalterung für die Eigenschaftskonfiguration, die Schnittstellen, die endgültigen Zeichenfolgen usw. fließen.

Wenn Sie die Ausrede verwenden müssen, eine Komponente zu finden, die leichter anhand von Schnittstellenkonstanten zu diktieren ist, bedeutet dies, dass Sie die schlechte Angewohnheit haben, die Normalisierung von Datenmodellen nicht zu üben.

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

In Schnittstellen definierte Werte sind vollständig unveränderlich. Und teilbar. Warum sollten Sie eine Reihe von endgültigen Zeichenfolgen aus einer anderen Klasse in Ihre Klasse laden, wenn Sie nur diese Konstanten benötigen?

Warum also nicht einen Datenmodellvertrag veröffentlichen? Ich meine, wenn Sie es kohärent verwalten und normalisieren können, 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 vereinbarten Etiketten meiner Apps wie folgt verweisen

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

Dies verwirrt den Inhalt der JAR-Datei? Als Java-Programmierer interessiert mich die Struktur des Jars nicht.

Dies stellt die Komplexität des osgi-motivierten Laufzeitaustauschs dar. Osgi ist ein äußerst effizientes Mittel, um Programmierern zu ermöglichen, ihre schlechten Gewohnheiten fortzusetzen. Es gibt bessere Alternativen als Osgi.

Oder warum nicht das? Es gibt kein Durchsickern der privaten Konstanten in den veröffentlichten Vertrag. Alle privaten Konstanten sollten in einer privaten Schnittstelle mit dem Namen "Konstanten" gruppiert werden, da ich nicht nach Konstanten suchen muss und zu faul bin, um wiederholt "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 mit Schnittstellenkonstanten, das berücksichtigt werden sollte, ist die Implementierung der Schnittstelle.

Dies ist nicht die "ursprüngliche Absicht" von Schnittstellen? Als würde mir die "ursprüngliche Absicht" der Gründerväter bei der Ausarbeitung der US-Verfassung am Herzen liegen, anstatt wie der Oberste Gerichtshof die schriftlichen Briefe der US-Verfassung interpretieren würde ???

Immerhin lebe ich im Land der Freien, der Wildnis und der Heimat der Tapferen. Sei mutig, sei frei, sei wild - benutze die Schnittstelle. Wenn meine Programmierkollegen sich weigern, effiziente und faule Programmiermittel zu verwenden, bin ich dann nach der goldenen Regel verpflichtet, meine Programmiereffizienz zu verringern, um sie an ihre anzupassen? Vielleicht sollte ich, aber das ist keine ideale Situation.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.