Domanda

Ho visto esempi come questo:

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

e supponevo di poter avere una classe Constants in cui racchiudere le costanti, dichiarandole statiche finali.Non conosco praticamente Java e mi chiedo se questo sia il modo migliore per creare costanti.

È stato utile?

Soluzione

Questo è perfettamente accettabile, probabilmente anche lo standard.

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

Dove TYPE è il tipo, NAME è il nome tutto maiuscolo con trattini bassi per gli spazi e VALUE è il valore costante;

Consiglio vivamente di NON inserire le costanti nelle proprie classi o interfacce.

Come nota a margine:Le variabili dichiarate definitive e mutabili possono ancora essere modificate;tuttavia, la variabile non può mai puntare a un oggetto diverso.

Per esempio:

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

public static void main(String[] args){

    ORIGIN.x = 3;

}

Questo è legale e ORIGIN sarebbe quindi un punto in (3, 0).

Altri suggerimenti

Consiglio vivamente di non avere un'unica classe di costanti.Può sembrare una buona idea in quel momento, ma quando gli sviluppatori si rifiutano di documentare le costanti e la classe cresce fino a comprendere più di 500 costanti che non sono affatto correlate tra loro (essendo correlate ad aspetti completamente diversi dell'applicazione), questo generalmente rende il file delle costanti completamente illeggibile.Invece:

  • Se hai accesso a Java 5+, utilizza le enumerazioni per definire le costanti specifiche per un'area di applicazione.Tutte le parti dell'area dell'applicazione dovrebbero fare riferimento a enumerazioni, non a valori costanti, per queste costanti.Puoi dichiarare un'enumerazione in modo simile a come dichiari una classe.Le enumerazioni sono forse la caratteristica più (e, probabilmente, l'unica) utile di Java 5+.
  • Se disponi di costanti valide solo per una particolare classe o una delle sue sottoclassi, dichiarale protette o pubbliche e posizionale nella classe più alta della gerarchia.In questo modo, le sottoclassi possono accedere a questi valori costanti (e se altre classi vi accedono tramite public, le costanti non sono valide solo per una classe particolare... il che significa che le classi esterne che utilizzano questa costante potrebbero essere troppo strettamente collegate alla classe contenente la costante)
  • Se si dispone di un'interfaccia con un comportamento definito, ma i valori restituiti o i valori degli argomenti devono essere particolari, è perfettamente accettabile definire costanti su quell'interfaccia in modo che altri implementatori possano accedervi.Tuttavia, evita di creare un'interfaccia solo per contenere costanti:può diventare altrettanto dannoso di una classe creata solo per contenere costanti.

È un PRATICA CATTIVA per utilizzare le interfacce solo per contenere costanti (denominate modello di interfaccia costante di Josh Bloch).Ecco cosa consiglia Josh:

Se le costanti sono fortemente legate a una classe o interfaccia esistente, è necessario aggiungerle alla classe o all'interfaccia.Ad esempio, tutte le classi primitive numeriche in scatola, come intero e doppio, esportano le costanti Min_Value e Max_Value.Se le costanti sono meglio visualizzate come membri di un tipo elencato, è necessario esportarli con un enumtipo.Altrimenti, è necessario esportare le costanti con una classe di utilità non istituibile.

Esempio:

// 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;
}

Informazioni sulla convenzione di denominazione:

Per convenzione, tali campi hanno nomi costituiti da lettere maiuscole, con parole separate da sottoti.È fondamentale che questi campi contengano valori primitivi o riferimenti a oggetti immutabili.

In Effective Java (2a edizione), è consigliabile utilizzare enumerazioni invece di numeri interi statici per le costanti.

C'è un buon articolo sulle enumerazioni in Java qui:http://java.sun.com/j2se/1.5.0/docs/guide/lingual/enums.html

Si noti che alla fine di quell'articolo la domanda posta è:

Quindi quando dovresti usare le enumerazioni?

Con una risposta di:

Ogni volta che hai bisogno di un insieme fisso di costanti

Evita semplicemente di usare un'interfaccia:

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

public class NeddsConstant implements MyConstants {

}

È allettante, ma viola l'incapsulamento e offusca la distinzione delle definizioni di classe.

Utilizzo il seguente approccio:

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() {}
}

Quello che, ad esempio, uso Constants.DB.Connection.URL per diventare costante.Sembra più "orientato agli oggetti" per quanto mi riguarda.

Creare costanti finali statiche in una classe separata può metterti nei guai.Il compilatore Java lo ottimizzerà effettivamente e inserirà il valore effettivo della costante in qualsiasi classe che vi faccia riferimento.

Se in seguito modifichi la classe "Costanti" e non esegui una ricompilazione dura su altre classi che fanno riferimento a quella classe, ti ritroverai con una combinazione di valori vecchi e nuovi utilizzati.

Invece di considerarli come costanti, pensali come parametri di configurazione e crea una classe per gestirli.Assicurati che i valori non siano definitivi e considera anche l'utilizzo dei getter.In futuro, quando si determinerà che alcuni di questi parametri devono effettivamente essere configurabili dall'utente o dall'amministratore, sarà molto più semplice farlo.

L'errore numero uno che puoi commettere è creare una classe accessibile a livello globale chiamata con un nome generico, come Constants.Questo viene semplicemente ricoperto di spazzatura e perdi ogni capacità di capire quale parte del tuo sistema utilizza queste costanti.

Invece, le costanti dovrebbero entrare nella classe che le "possiede".Hai una costante chiamata TIMEOUT?Probabilmente dovrebbe andare nella classe Communications() o Connection().MAX_BAD_LOGINS_PER_ORA?Entra in Utente().E così via e così via.

L'altro utilizzo possibile sono i file Java .properties quando le "costanti" possono essere definite in fase di esecuzione, ma non facilmente modificabili dall'utente.Puoi impacchettarli nei tuoi file .jar e farvi riferimento con Class ResourceLoader.

Questa è la strada giusta da percorrere.

Generalmente le costanti lo sono non mantenuti in classi "costanti" separate perché non sono rilevabili.Se la costante è rilevante per la classe corrente, mantenerla lì aiuta lo sviluppatore successivo.

Che ne dici di un'enumerazione?

Preferisco usare getter piuttosto che costanti.Questi getter potrebbero restituire valori costanti, ad es. public int getMaxConnections() {return 10;}, ma tutto ciò che necessita della costante passerà attraverso un getter.

Un vantaggio è che se il tuo programma supera la costante (scopri che deve essere configurabile) puoi semplicemente cambiare il modo in cui il getter restituisce la costante.

L'altro vantaggio è che per modificare la costante non è necessario ricompilare tutto ciò che la utilizza.Quando fai riferimento a un campo finale statico, il valore di quella costante viene compilato in qualsiasi bytecode che fa riferimento ad esso.

Sono d'accordo che l'utilizzo di un'interfaccia non è la strada da percorrere.Evitare questo schema ha anche il suo oggetto (#18) in Bloch Java efficace.

Un argomento che Bloch avanza contro il modello di interfaccia costante è che l'uso delle costanti è un dettaglio di implementazione, ma l'implementazione di un'interfaccia per usarle espone quel dettaglio di implementazione nell'API esportata.

IL public|private static final TYPE NAME = VALUE; pattern è un buon modo per dichiarare una costante.Personalmente, penso che sia meglio evitare di creare una classe separata per ospitare tutte le tue costanti, ma non ho mai visto un motivo per non farlo, oltre alle preferenze e allo stile personali.

Se le tue costanti possono essere ben modellate come un'enumerazione, considera il enum struttura disponibile in 1.5 o successiva.

Se stai utilizzando una versione precedente alla 1.5, puoi comunque eseguire enumerazioni typesafe utilizzando le normali classi Java.(Vedere questo sito per saperne di più).

Sulla base dei commenti sopra, penso che questo sia un buon approccio per cambiare la classe costante globale vecchio stile (con variabili finali statiche pubbliche) nel suo equivalente simile a un'enumerazione in un modo come questo:

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;
    }

}

Quindi posso fare riferimento a loro come:

Constants.StringConstant.DB_HOST

Una buona progettazione orientata agli oggetti non dovrebbe aver bisogno di molte costanti disponibili pubblicamente.La maggior parte delle costanti dovrebbero essere incapsulate nella classe che ne ha bisogno per svolgere il proprio lavoro.

C'è una certa quantità di opinioni per rispondere a questa domanda.Per cominciare, le costanti in Java sono generalmente dichiarate pubbliche, statiche e finali.Di seguito sono riportati i motivi:

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

Non utilizzerei mai un'interfaccia per una funzione di accesso/oggetto CONSTANTS semplicemente perché generalmente ci si aspetta che le interfacce siano implementate.Non sembrerebbe divertente:

String myConstant = IMyInterface.CONSTANTX;

Sceglierei invece tra alcuni modi diversi, basati su alcuni piccoli compromessi, e quindi dipende da ciò di cui hai bisogno:

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

Qual è il modo migliore per implementare le costanti in Java?

Un approccio che dovremmo davvero evitare :utilizzare le interfacce per definire le costanti.

Creare un'interfaccia specifica per dichiarare le costanti è davvero la cosa peggiore:vanifica il motivo per cui sono state progettate le interfacce:definizione del contratto dei metodi.

Anche se esiste già un'interfaccia per soddisfare un'esigenza specifica, dichiarare le costanti al suo interno non ha davvero senso poiché le costanti non dovrebbero far parte dell'API e del contratto fornito alle classi client.


Per semplificare, abbiamo sostanzialmente 4 approcci validi.

Con static final String/Integer campo :

  • 1) utilizzando una classe che dichiari costanti al suo interno ma non solo.
  • 1 variante) creando una classe dedicata solo a dichiarare costanti.

Con Java 5 enum :

  • 2) dichiarare l'enumerazione in una classe di scopo correlata (quindi come una classe nidificata).
  • 2 variante) creando l'enumerazione come classe autonoma (così definita nel proprio file di classe).

TLDR:Qual è il modo migliore e dove individuare le costanti?

Nella maggior parte dei casi, il metodo enum è probabilmente più preciso di quello static final String/Integer modo e personalmente penso che il static final String/Integer way dovrebbe essere utilizzato solo se abbiamo buone ragioni per non utilizzare le enumerazioni.
E su dove dovremmo dichiarare i valori costanti, l'idea è quella di ricercare se esista un'unica classe che possieda una specifica e forte coesione funzionale con valori costanti.Se troviamo una classe del genere, dovremmo usarla come contenitore delle costanti.Altrimenti, la costante non dovrebbe essere associata a nessuna classe particolare.


static final String/ static final Integer contro enum

L'utilizzo delle enumerazioni è davvero un modo da considerare fortemente.
Le enumerazioni hanno un grande vantaggio rispetto a String O Integer campo costante.
Impongono un vincolo di compilazione più forte.Se definisci un metodo che accetta l'enum come parametro, puoi passare solo un valore enum definito nella classe enum (o null).
Con String e Integer puoi sostituirli con qualsiasi valore di tipo compatibile e la compilazione andrà bene anche se il valore non è una costante definita nel static final String/ static final Integer campi.

Ad esempio, di seguito due costanti definite in una classe come static final String campi :

public class MyClass{

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

Ecco un metodo che prevede di avere una di queste costanti come parametro:

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

Puoi invocarlo in questo modo:

process(MyClass.ONE_CONSTANT);

O

process(MyClass.ANOTHER_CONSTANT);

Ma nessun vincolo di compilazione ti impedisce di invocarlo in questo modo:

process("a not defined constant value");

Avresti l'errore solo a runtime e solo se fai per volta un controllo sul valore trasmesso.

Con enum, i controlli non sono richiesti poiché il client può solo passare un valore enum in un parametro enum.

Ad esempio, qui due valori definiti in una classe enum (quindi costante fuori dagli schemi):

public enum MyEnum {

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

    private String value;

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

Ecco un metodo che prevede di avere uno di questi valori enum come parametro:

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

Puoi invocarlo in questo modo:

process(MyEnum.ONE_CONSTANT);

O

process(MyEnum.ANOTHER_CONSTANT);

Ma la compilazione non ti permetterà mai di invocarla in questo modo:

process("a not defined constant value");

Dove dovremmo dichiarare le costanti?

Se la vostra applicazione contiene un'unica classe esistente che possiede una specifica e forte coesione funzionale con i valori costanti, la 1) e la 2) appaiono più intuitive.
In genere, si facilita l'uso delle costanti se queste vengono dichiarate nella classe principale che le manipola o che ha un nome molto naturale per indovinare che troveremo al suo interno.

Ad esempio, nella libreria JDK, i valori esponenziale e costante pi sono dichiarati in una classe che dichiara non solo dichiarazioni costanti (java.lang.Math).

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

I clienti che utilizzano funzioni matematiche si affidano spesso a Math classe.Quindi, possono trovare costanti abbastanza facilmente e possono anche ricordare dove E E PI sono definiti in modo molto naturale.

Se la tua applicazione non contiene una classe esistente che abbia una coesione funzionale molto specifica e forte con i valori costanti, i modi 1 variante) e 2 variante) appaiono più intuitivi.
In generale, non facilita l'uso delle costanti se queste vengono dichiarate in una classe che le manipola mentre abbiamo anche 3 o 4 altre classi che le manipolano tanto e nessuna di queste classi sembra essere più naturale delle altre nel farlo ospitare valori costanti.
In questo caso ha senso definire una classe personalizzata per contenere solo valori costanti.
Ad esempio nella libreria JDK, il file java.util.concurrent.TimeUnit enum non è dichiarato in una classe specifica in quanto non esiste in realtà una e una sola classe specifica JDK che appaia come la più intuitiva per mantenerla:

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

Molte classi dichiarate in java.util.concurrent usali:BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , ...e in realtà nessuno di loro sembra più appropriato per detenere l'enum.

Una Costante, di qualsiasi tipo, può essere dichiarata creando una proprietà immutabile che all'interno di una classe (cioè una variabile membro con final modificatore).Tipicamente il static E public vengono forniti anche i modificatori.

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

Esistono numerose applicazioni in cui il valore di una costante indica una selezione da una n-tupla (ad es. enumerazione) di scelte.Nel nostro esempio, possiamo scegliere di definire un tipo enumerato che limiterà i possibili valori assegnati (ad es.migliorato sicurezza del tipo):

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

Una singola classe di costanti generiche è una cattiva idea.Le costanti dovrebbero essere raggruppate insieme alla classe a cui sono più logicamente correlate.

Invece di utilizzare variabili di qualsiasi tipo (specialmente enumerazioni), suggerirei di utilizzare metodi.Crea un metodo con lo stesso nome della variabile e chiedigli di restituire il valore che hai assegnato alla variabile.Ora elimina la variabile e sostituisci tutti i riferimenti ad essa con chiamate al metodo appena creato.Se ritieni che la costante sia abbastanza generica da non dover creare un'istanza della classe solo per usarla, allora rendi il metodo costante un metodo di classe.

FWIW, un valore di timeout in secondi dovrebbe probabilmente essere un'impostazione di configurazione (letta da un file delle proprietà o tramite iniezione come in Spring) e non una costante.

Qual è la differenza

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;
}

e utilizzandoMyGlobalConstants.TIMEOUT_IN_SECS ovunque abbiamo bisogno di questa costante.Penso che entrambi siano uguali.

Non chiamerei la classe uguale (a parte l'involucro) alla costante ...Avrei almeno una classe di "Impostazioni", o "Valori" o "Costanti", in cui vivrebbero tutte le costanti.Se ne ho un gran numero, li raggrupperò in classi costanti logiche (UserSettings, AppSettings, ecc.)

Per fare un ulteriore passo avanti, è possibile inserire costanti utilizzate a livello globale in un'interfaccia in modo che possano essere utilizzate a livello di sistema.Per esempio.

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

Ma non implementarlo.Basta fare riferimento a loro direttamente nel codice tramite il nome classe completo.

Per Constants, Enum è una scelta migliore IMHO.Ecco un esempio

classe pubblica miaClasse {

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

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


}

Uno dei modi in cui lo faccio è creare una classe "globale" con i valori costanti ed eseguire un'importazione statica nelle classi che necessitano di accesso alla costante.

static final è la mia preferenza, userei solo an enum se l'elemento fosse effettivamente enumerabile.

Io uso static final per dichiarare costanti e utilizzare la notazione di denominazione ALL_CAPS.Ho visto parecchi casi di vita reale in cui tutte le costanti sono raggruppate in un'interfaccia.Alcuni post l'hanno giustamente definita una cattiva pratica, principalmente perché non è a questo che serve un'interfaccia.Un'interfaccia dovrebbe far rispettare un contratto e non dovrebbe essere un luogo in cui inserire costanti non correlate.Anche metterlo insieme in una classe che non può essere istanziata (tramite un costruttore privato) va bene se la semantica costante non appartiene a una o più classi specifiche.Inserisco sempre una costante nella classe a cui è maggiormente correlata, perché ha senso ed è anche facilmente gestibile.

Le enumerazioni sono una buona scelta per rappresentare un intervallo di valori, ma se stai memorizzando costanti autonome con un'enfasi sul valore assoluto (ad es.TIMEOUT = 100 ms) puoi semplicemente scegliere il static final approccio.

Sono d'accordo con ciò che dice la maggior parte, è meglio usare le enumerazioni quando si ha a che fare con una raccolta di costanti.Tuttavia, se stai programmando in Android esiste una soluzione migliore: Annotazione IntDef.

@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();

L'annotazione IntDef è superiore alle enumerazioni in un modo semplice: occupa molto meno spazio poiché è semplicemente un indicatore in fase di compilazione.Non è una classe, né ha la proprietà di conversione automatica delle stringhe.

È Cattiva abitudine e pratica terribilmente fastidiosa per citare Joshua Bloch senza comprendere il fondamentalismo fondamentale del punto zero.

Non ho letto nemmeno niente di Joshua Bloch

  • è un pessimo programmatore
  • oppure le persone che finora ho scoperto che lo citano (Joshua è il nome di un ragazzo, presumo) stanno semplicemente usando il suo materiale come script religiosi per giustificare le loro indulgenze religiose sul software.

Come nel fondamentalismo biblico, tutte le leggi bibliche possono essere riassunte in:

  • Amate l'Identità Fondamentale con tutto il cuore e con tutta la mente
  • Ama il tuo prossimo come te stesso

e così si può riassumere in modo simile il fondamentalismo dell’ingegneria del software

  • dedicati ai fondamenti fondamentali con tutta la tua forza e mente di programmazione
  • e dedicati all'eccellenza dei tuoi colleghi programmatori come faresti per te stesso.

Anche tra gli ambienti fondamentalisti biblici si delinea un forte e ragionevole corollario

  • Prima Ama te stesso.Perché se non ami molto te stesso, allora il concetto "ama il tuo prossimo come te stesso" non ha molto peso, poiché "quanto ami te stesso" è la linea di riferimento al di sopra della quale amerai gli altri.

Allo stesso modo, se non rispetti te stesso come programmatore e accetti semplicemente le dichiarazioni e le profezie di qualche guru della programmazione-nath SENZA mettere in discussione i fondamenti, le tue citazioni e il tuo affidamento a Joshua Bloch (e simili) non hanno senso.E quindi, in realtà non avresti rispetto per i tuoi colleghi programmatori.

Le leggi fondamentali della programmazione del software

  • la pigrizia è la virtù di un buon programmatore
  • devi rendere la tua vita di programmazione il più semplice, pigra e quindi il più efficace possibile
  • devi rendere le conseguenze e le viscere della tua programmazione il più semplici, pigre e quindi efficaci possibile per i tuoi vicini programmatori che lavorano con te e raccolgono le tue viscere di programmazione.

Le costanti del modello di interfaccia sono una cattiva abitudine ???

In quali leggi di programmazione fondamentalmente efficace e responsabile rientra questo editto religioso?

Basta leggere l'articolo di Wikipedia sulle costanti del modello di interfaccia (https://en.wikipedia.org/wiki/Constant_interface) e le sciocche scuse che adduce contro le costanti del modello di interfaccia.

  • E se-nessun IDE?Chi mai come programmatore di software non utilizzerebbe un IDE?La maggior parte di noi sono programmatori che preferiscono non dover dimostrare di avere un survivalismo ascetico macho evitando l'uso di un IDE.

    • Inoltre, aspettate un secondo dai sostenitori della programmazione microfunzionale come mezzo per non aver bisogno di un IDE.Aspetta di leggere la mia spiegazione sulla normalizzazione del modello di dati.
  • Inquina lo spazio dei nomi con variabili non utilizzate nell'ambito corrente?Potrebbero essere sostenitori di questa opinione

    • non sono consapevoli della necessità di normalizzazione del modello di dati
  • Usare le interfacce per imporre costanti è un abuso delle interfacce.I sostenitori di ciò hanno la cattiva abitudine di

    • non vedendo che le "costanti" devono essere trattate come contratto.E le interfacce vengono utilizzate per far rispettare o proiettare la conformità a un contratto.
  • È difficile se non impossibile convertire le interfacce in classi implementate in futuro.Ahah....hmmm...???

    • Perché vorresti impegnarti in questo modello di programmazione come tuo sostentamento persistente?IOW, perché dedicarsi ad un'abitudine di programmazione così AMBIVALENTE e pessima?

Qualunque siano le scuse, NON ESISTE SCUSA VALIDA quando si tratta di ingegneria del software FONDAMENTALMENTE EFFICACE per delegittimare o in generale scoraggiare l'uso delle costanti di interfaccia.

Non importa quali fossero gli intenti originali e gli stati mentali dei padri fondatori che crearono la Costituzione degli Stati Uniti.Potremmo discutere sugli intenti originali dei padri fondatori, ma tutto ciò che mi interessa sono le dichiarazioni scritte della Costituzione degli Stati Uniti.Ed è responsabilità di ogni cittadino americano sfruttare il fondamentalismo letterario scritto, e non gli intenti fondativi non scritti, della Costituzione americana.

Allo stesso modo, non mi interessa quali fossero gli intenti "originali" dei fondatori della piattaforma Java e del linguaggio di programmazione per l'interfaccia.Ciò che mi interessa sono le funzionalità efficaci fornite dalle specifiche Java e intendo sfruttare tali funzionalità al massimo per aiutarmi a soddisfare le leggi fondamentali della programmazione software responsabile.Non mi interessa se vengo percepito come "violare l'intenzione delle interfacce".Non mi interessa cosa dicono Gosling o qualcuno Bloch riguardo al "modo corretto di usare Java", a meno che ciò che dicono non violi la mia necessità di soddisfare i fondamenti EFFICACI.

La cosa fondamentale è la normalizzazione del modello di dati

Non importa come il tuo modello di dati è ospitato o trasmesso.Sia che utilizzi interfacce o enumerazioni o altro, relazionali o no-SQL, se non capisci la necessità e il processo di normalizzazione del modello di dati.

Dobbiamo prima definire e normalizzare il modello dati di un insieme di processi.E quando disponiamo di un modello di dati coerente, SOLO allora possiamo utilizzare il flusso di processo dei suoi componenti per definire il comportamento funzionale e bloccare i processi in un campo o ambito di applicazioni.E solo allora potremo definire l'API di ciascun processo funzionale.

Anche gli aspetti della normalizzazione dei dati proposta da EF Codd sono ora seriamente messi a dura prova e messi a dura prova.per esempio.la sua dichiarazione su 1NF è stata criticata come ambigua, disallineata ed eccessivamente semplificata, così come il resto delle sue dichiarazioni, soprattutto con l'avvento dei moderni servizi dati, della tecnologia repo e della trasmissione.Secondo l'IMO, le affermazioni di EF Codd dovrebbero essere completamente abbandonate e dovrebbe essere progettata una nuova serie di affermazioni matematicamente più plausibili.

Un evidente difetto di EF Codd e la causa del suo disallineamento rispetto all'effettiva comprensione umana è la sua convinzione che i dati multidimensionali e di dimensione mutabile umanamente percepibili possano essere percepiti in modo efficiente attraverso una serie di mappature bidimensionali frammentarie.

I fondamenti della normalizzazione dei dati

Ciò che EF Codd non è riuscito a esprimere.

All'interno di ciascun modello di dati coerente, questi sono gli ordini sequenziali e graduali di coerenza del modello di dati da raggiungere.

  1. L'unità e l'identità delle istanze di dati.
    • progettare la granularità di ciascun componente di dati, in modo che la granularità sia a un livello in cui ciascuna istanza di un componente possa essere identificata e recuperata in modo univoco.
    • assenza di aliasing delle istanze.cioè, non esiste alcun mezzo per cui un'identificazione produca più di un'istanza di un componente.
  2. Assenza di diafonia delle istanze.Non esiste la necessità di utilizzare una o più altre istanze di un componente per contribuire ad identificare un'istanza di un componente.
  3. L'unità e l'identità delle componenti/dimensioni dei dati.
    • Presenza di de-aliasing dei componenti.Deve esistere una definizione in base alla quale un componente/dimensione può essere identificato in modo univoco.Qual è la definizione principale di un componente;
    • dove la definizione primaria non comporterà l'esposizione di sottodimensioni o componenti di membri che non fanno parte di un componente previsto;
  4. Mezzi unici di dealiasing dei componenti.Deve esistere una, e una sola, definizione di dealalising del componente per un componente.
  5. Esiste una, e una sola, interfaccia o contratto di definizione per identificare un componente principale in una relazione gerarchica di componenti.
  6. Assenza di diafonia dei componenti.Non esiste la necessità di utilizzare un membro di un altro componente per contribuire all'identificazione definitiva di un componente.
    • In tale relazione genitore-figlio, la definizione identificativa di genitore non deve dipendere da parte dell'insieme dei componenti membri di un figlio.Un componente membro dell'identità di un genitore deve essere l'identità completa del figlio senza fare riferimento a uno o tutti i figli di un figlio.
  7. Prevenire gli aspetti bimodali o multimodali di un modello di dati.
    • Quando esistono due definizioni candidate di un componente, è un segno evidente che esistono due diversi modelli di dati mescolati in uno solo.Ciò significa che c’è incoerenza a livello di modello di dati o a livello di campo.
    • Un campo di applicazioni deve utilizzare uno ed un solo modello dati, in modo coerente.
  8. Rilevare e identificare la mutazione dei componenti.A meno che non sia stata eseguita l'analisi statistica delle componenti di dati enormi, probabilmente non si vede, o non si vede la necessità di trattare, la mutazione dei componenti.
    • Un modello di dati può subire una mutazione ciclica o graduale di alcuni dei suoi componenti.
    • La modalità può essere rotazione-membri o rotazione-trasposizione.
    • La mutazione della rotazione dei membri potrebbe essere uno scambio distinto di componenti figlio tra componenti.O dove si dovrebbero definire componenti completamente nuovi.
    • La mutazione trasposizionale si manifesterebbe come una mutazione di un membro dimensionale in un attributo, e viceversa.
    • Ciascun ciclo di mutazione deve essere identificato come un modello di dati distinto.
  9. Versionizza ogni mutazione.In modo tale da poter estrarre una versione precedente del modello di dati, quando forse si presenta la necessità di trattare una mutazione del modello di dati di 8 anni fa.

In un campo o griglia di applicazioni di componenti interservizi, deve esserci uno e un solo modello di dati coerente oppure esiste un mezzo affinché un modello di dati/versione possa identificarsi.

Ci stiamo ancora chiedendo se potremmo usare le costanti dell'interfaccia?Veramente ?

Ci sono in gioco problemi di normalizzazione dei dati più consequenziali di questa domanda banale.SE non risolvi questi problemi, la confusione che ritieni causata dalle costanti dell'interfaccia è relativamente nulla.Niente da fare.

Dalla normalizzazione del modello dati si determinano quindi i componenti come variabili, come proprietà, come costanti dell'interfaccia del contratto.

Quindi determini cosa va inserito nell'iniezione di valore, nel segnaposto della configurazione delle proprietà, nelle interfacce, nelle stringhe finali, ecc.

Se devi usare la scusa di dover individuare un componente più facile da dettare rispetto alle costanti dell'interfaccia, significa che hai la cattiva abitudine di non praticare la normalizzazione del modello dati.

Forse desideri compilare il modello dati in una versione vcs.Che puoi estrarre una versione distintamente identificabile di un modello di dati.

È assolutamente garantito che i valori definiti nelle interfacce non siano modificabili.E condivisibile.Perché caricare un insieme di stringhe finali nella tua classe da un'altra classe quando tutto ciò di cui hai bisogno è quell'insieme di costanti?

Allora perché non pubblicare un contratto basato sul modello dei dati?Voglio dire, se riesci a gestirlo e normalizzarlo in modo coerente, perché no?...

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"
      }
    }
  }
}

Ora posso fare riferimento alle etichette contrattate delle mie app in un modo come

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

Questo confonde il contenuto del file jar?Come programmatore Java non mi interessa la struttura del jar.

Ciò presenta complessità per lo scambio di runtime motivato da OSGI?Osgi è un mezzo estremamente efficiente per consentire ai programmatori di continuare nelle loro cattive abitudini.Esistono alternative migliori rispetto a osgi.

Oppure perché non questo?Non vi è alcuna perdita di costanti private nel contratto pubblicato.Tutte le costanti private dovrebbero essere raggruppate in un'interfaccia privata denominata "Costanti", perché non voglio dover cercare costanti e sono troppo pigro per digitare ripetutamente "stringa finale privata".

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

Forse anche questo:

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

L'unico problema con le costanti dell'interfaccia che vale la pena considerare è quando l'interfaccia viene implementata.

Non è questa l'"intenzione originale" delle interfacce?Ad esempio, mi preoccuperei dell '"intenzione originale" dei padri fondatori nel creare la Costituzione degli Stati Uniti, piuttosto che di come la Corte Suprema interpreterebbe le lettere scritte della Costituzione degli Stati Uniti ???

Dopotutto, vivo nella terra dei liberi, dei selvaggi e della patria dei coraggiosi.Sii coraggioso, sii libero, sii selvaggio: usa l'interfaccia.Se i miei colleghi programmatori si rifiutano di utilizzare mezzi di programmazione efficienti e pigri, sono obbligato dalla regola d'oro a ridurre la mia efficienza di programmazione per allinearmi alla loro?Forse dovrei, ma non è una situazione ideale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top