Pergunta

Já vi exemplos como este:

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

e suponho que eu poderia ter uma classe Constants para agrupar as constantes, declarando-as estáticas como finais.Não conheço praticamente nenhum Java e estou me perguntando se esta é a melhor maneira de criar constantes.

Foi útil?

Solução

Isso é perfeitamente aceitável, provavelmente até mesmo o padrão.

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

onde TYPE é o tipo, NAME é o nome em letras maiúsculas com sublinhados para espaços, e VALUE é o valor constante;

Eu recomendo NÃO colocar suas constantes em suas próprias classes ou interfaces.

Como uma nota rodapé:Variáveis ​​declaradas finais e mutáveis ​​ainda podem ser alteradas;entretanto, a variável nunca pode apontar para um objeto diferente.

Por exemplo:

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

public static void main(String[] args){

    ORIGIN.x = 3;

}

Isso é legal e ORIGIN seria então um ponto em (3, 0).

Outras dicas

Eu recomendo fortemente não ter uma única classe de constantes.Pode parecer uma boa ideia no momento, mas quando os desenvolvedores se recusam a documentar constantes e a classe cresce para abranger mais de 500 constantes que não estão relacionadas entre si (sendo relacionadas a aspectos totalmente diferentes da aplicação), isso geralmente torna o arquivo de constantes completamente ilegível.Em vez de:

  • Se você tiver acesso ao Java 5+, use enums para definir suas constantes específicas para uma área de aplicativo.Todas as partes da área de aplicação devem referir-se a enums, e não a valores constantes, para essas constantes.Você pode declarar um enum semelhante a como declara uma classe.Enums são talvez o recurso mais (e, sem dúvida, o único) útil do Java 5+.
  • Se você tiver constantes válidas apenas para uma classe específica ou uma de suas subclasses, declare-as como protegidas ou públicas e coloque-as na classe superior da hierarquia.Dessa forma, as subclasses podem acessar esses valores constantes (e se outras classes os acessarem via pública, as constantes não são válidas apenas para uma classe específica... o que significa que as classes externas que usam essa constante podem estar fortemente acopladas ao classe contendo a constante)
  • Se você possui uma interface com comportamento definido, mas os valores retornados ou os valores dos argumentos devem ser específicos, é perfeitamente aceitável definir constantes nessa interface para que outros implementadores tenham acesso a elas.Entretanto, evite criar uma interface apenas para manter constantes:pode se tornar tão ruim quanto uma classe criada apenas para manter constantes.

É um MÁ PRÁTICA usar interfaces apenas para manter constantes (chamadas padrão de interface constante por Josh Bloch).Aqui está o que Josh aconselha:

Se as constantes estiverem fortemente ligadas a uma classe ou interface existente, você deve adicioná-los à classe ou interface.Por exemplo, todos os classes primitivas numéricas encaixotadas, como Inteiro e Duplo, exportar MIN_VALUE e MAX_VALUE constantes.Se as constantes são melhor vistas como membros de um tipo enumerado, você deve exportá-los com um enumeraçãotipo.Caso contrário, você deve exportar o constantes com um não instanciável classe de utilidade.

Exemplo:

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

Sobre a convenção de nomenclatura:

Por convenção, esses campos têm nomes composto por letras maiúsculas, com palavras separadas por sublinhados.Pois é crítico que esses campos contenham valores primitivos ou referências a objetos imutáveis.

Em Effective Java (2ª edição), é recomendado que você use enums em vez de static ints para constantes.

Há um bom artigo sobre enums em Java aqui:http://java.sun.com/j2se/1.5.0/docs/guide/linguagem/enums.html

Observe que no final desse artigo a questão colocada é:

Então, quando você deve usar enums?

Com uma resposta de:

Sempre que você precisar de um conjunto fixo de constantes

Apenas evite usar uma interface:

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

public class NeddsConstant implements MyConstants {

}

É tentador, mas viola o encapsulamento e confunde a distinção das definições de classe.

Eu uso a seguinte abordagem:

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

Do que, por exemplo, eu uso Constants.DB.Connection.URL para ficar constante.Parece mais "orientado ao objeto" quanto a mim.

Criar constantes finais estáticas em uma classe separada pode causar problemas.O compilador Java irá realmente otimizar isso e colocar o valor real da constante em qualquer classe que a referencie.

Se mais tarde você alterar a classe 'Constantes' e não fizer uma recompilação forçada em outras classes que fazem referência a essa classe, você acabará com uma combinação de valores antigos e novos sendo usados.

Em vez de pensar neles como constantes, pense neles como parâmetros de configuração e crie uma classe para gerenciá-los.Faça com que os valores não sejam finais e considere até mesmo o uso de getters.No futuro, conforme você determinar que alguns desses parâmetros realmente devem ser configurados pelo usuário ou administrador, será muito mais fácil fazer isso.

O erro número um que você pode cometer é criar uma classe acessível globalmente chamada com um nome genérico, como Constantes.Isso simplesmente fica cheio de lixo e você perde toda a capacidade de descobrir qual parte do seu sistema usa essas constantes.

Em vez disso, as constantes devem ir para a classe que as “possui”.Você tem uma constante chamada TIMEOUT?Provavelmente deve entrar na sua classe Communications() ou Connection().MAX_BAD_LOGINS_PER_HOUR?Entra em Usuário().E assim por diante.

O outro uso possível são os arquivos Java .properties, quando "constantes" podem ser definidas em tempo de execução, mas não podem ser facilmente alteradas pelo usuário.Você pode empacotá-los em seus .jars e referenciá-los com a classe resourceLoader.

Esse é o caminho certo a seguir.

Geralmente constantes são não mantidos em classes "Constantes" separadas porque não podem ser descobertos.Se a constante for relevante para a classe atual, mantê-la lá ajuda o próximo desenvolvedor.

E uma enumeração?

Prefiro usar getters em vez de constantes.Esses getters podem retornar valores constantes, por ex. public int getMaxConnections() {return 10;}, mas qualquer coisa que precise da constante passará por um getter.

Um benefício é que se o seu programa superar a constante - você descobrirá que ele precisa ser configurável - você poderá simplesmente alterar a forma como o getter retorna a constante.

O outro benefício é que para modificar a constante você não precisa recompilar tudo que a utiliza.Quando você faz referência a um campo final estático, o valor dessa constante é compilado em qualquer bytecode que faça referência a ele.

Concordo que usar uma interface não é o caminho a percorrer.Evitar esse padrão tem até seu próprio item (#18) no livro de Bloch. Java eficaz.

Um argumento que Bloch apresenta contra o padrão de interface constante é que o uso de constantes é um detalhe de implementação, mas a implementação de uma interface para usá-las expõe esse detalhe de implementação em sua API exportada.

O public|private static final TYPE NAME = VALUE; padrão é uma boa maneira de declarar uma constante.Pessoalmente, acho melhor evitar criar uma classe separada para abrigar todas as suas constantes, mas nunca vi uma razão para não fazer isso, além da preferência e estilo pessoal.

Se suas constantes puderem ser bem modeladas como uma enumeração, considere o enumeração estrutura disponível em 1.5 ou posterior.

Se você estiver usando uma versão anterior à 1.5, ainda poderá obter enumerações typesafe usando classes Java normais.(Ver esse site para saber mais sobre isso).

Com base nos comentários acima, acho que esta é uma boa abordagem para alterar a antiga classe constante global (tendo variáveis ​​finais estáticas públicas) para seu equivalente semelhante a enum, da seguinte maneira:

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

}

Então posso encaminhá-los para algo como:

Constants.StringConstant.DB_HOST

Um bom design orientado a objetos não deve precisar de muitas constantes disponíveis publicamente.A maioria das constantes deve ser encapsulada na classe que precisa delas para realizar seu trabalho.

Há uma certa quantidade de opinião para responder a isso.Para começar, as constantes em java são geralmente declaradas como públicas, estáticas e finais.Abaixo estão os motivos:

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

Eu nunca usaria uma interface para um acessador/objeto CONSTANTS simplesmente porque geralmente se espera que as interfaces sejam implementadas.Isso não pareceria engraçado:

String myConstant = IMyInterface.CONSTANTX;

Em vez disso, eu escolheria entre algumas maneiras diferentes, com base em algumas pequenas compensações, e isso depende do que você precisa:

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 é a melhor maneira de implementar constantes em Java?

Uma abordagem que deveríamos realmente evitar :usando interfaces para definir constantes.

Criar uma interface especificamente para declarar constantes é realmente a pior coisa:isso anula a razão pela qual as interfaces foram projetadas:definição de método(s) de contrato.

Mesmo que já exista uma interface para atender a uma necessidade específica, declarar as constantes nelas realmente não faz sentido, pois as constantes não devem fazer parte da API e do contrato fornecido às classes clientes.


Para simplificar, temos basicamente 4 abordagens válidas.

Com static final String/Integer campo :

  • 1) usando uma classe que declara constantes internas, mas não só.
  • 1 variante) criando uma classe dedicada apenas a declarar constantes.

Com Java 5 enum :

  • 2) declarar o enum em uma classe de propósito relacionada (como uma classe aninhada).
  • 2) criando o enum como uma classe autônoma (definida em seu próprio arquivo de classe).

TLDR:Qual é a melhor maneira e onde localizar as constantes?

Na maioria dos casos, o método enum é provavelmente mais refinado que o static final String/Integer caminho e pessoalmente penso que o static final String/Integer way deve ser usado somente se tivermos bons motivos para não usar enums.
E sobre onde devemos declarar os valores constantes, a ideia é pesquisar se existe uma única classe existente que possua uma coesão funcional específica e forte com valores constantes.Se encontrarmos tal classe, devemos usá-la como detentora de constantes.Caso contrário, a constante não deverá estar associada a nenhuma classe específica.


static final String/ static final Integer contra enum

O uso de enums é realmente uma forma de ser fortemente considerada.
Enums têm uma grande vantagem sobre String ou Integer campo constante.
Eles definem uma restrição de compilação mais forte.Se você definir um método que leva o enum como parâmetro, você só poderá passar um valor enum definido na classe enum (ou nulo).
Com String e Integer você pode substituí-los por quaisquer valores de tipo compatível e a compilação ficará bem mesmo que o valor não seja uma constante definida no static final String/ static final Integer Campos.

Por exemplo, abaixo de duas constantes definidas em uma classe como static final String Campos :

public class MyClass{

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

Aqui está um método que espera ter uma dessas constantes como parâmetro:

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

Você pode invocá-lo desta forma:

process(MyClass.ONE_CONSTANT);

ou

process(MyClass.ANOTHER_CONSTANT);

Mas nenhuma restrição de compilação impede que você o invoque desta forma:

process("a not defined constant value");

Você teria o erro apenas em tempo de execução e somente se fizer uma verificação simultânea do valor transmitido.

Com enum, as verificações não são necessárias, pois o cliente só pode passar um valor enum em um parâmetro enum.

Por exemplo, aqui estão dois valores definidos em uma classe enum (tão constantes fora da caixa):

public enum MyEnum {

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

    private String value;

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

Aqui está um método que espera ter um desses valores enum como parâmetro:

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

Você pode invocá-lo desta forma:

process(MyEnum.ONE_CONSTANT);

ou

process(MyEnum.ANOTHER_CONSTANT);

Mas a compilação nunca permitirá que você a invoque desta forma:

process("a not defined constant value");

Onde devemos declarar as constantes?

Se a sua aplicação contém uma única classe existente que possui uma coesão funcional específica e forte com os valores constantes, 1) e 2) parecem mais intuitivos.
Geralmente facilita o uso das constantes se estas forem declaradas na classe principal que as manipula ou que tenha um nome muito natural para adivinhar que o encontraremos dentro.

Por exemplo, na biblioteca JDK, os valores constantes exponenciais e pi são declarados em uma classe que declara não apenas declarações constantes (java.lang.Math).

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

Os clientes que usam funções matemáticas dependem frequentemente do Math aula.Assim, eles podem encontrar constantes com bastante facilidade e também lembrar onde E e PI são definidos de uma forma muito natural.

Se o seu aplicativo não contém uma classe existente que tenha uma coesão funcional muito específica e forte com os valores constantes, as formas 1 variante) e 2 variante) parecerão mais intuitivas.
Geralmente não facilita o uso das constantes se estas forem declaradas em uma classe que as manipula enquanto temos também 3 ou 4 outras classes que as manipulam tanto quanto e nenhuma dessas classes parece ser mais natural que outras para valores constantes do host.
Aqui, faz sentido definir uma classe personalizada para conter apenas valores constantes.
Por exemplo, na biblioteca JDK, o java.util.concurrent.TimeUnit enum não é declarado em uma classe específica, pois não existe realmente uma e apenas uma classe específica do JDK que pareça a mais intuitiva para mantê-la:

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

Muitas classes declaradas em java.util.concurrent usa-os :BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , ...e realmente nenhum deles parece mais apropriado para manter o enum.

Uma constante, de qualquer tipo, pode ser declarada criando uma propriedade imutável que dentro de uma classe (que é uma variável membro com o final modificador).Normalmente o static e public modificadores também são fornecidos.

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

Existem inúmeras aplicações onde o valor de uma constante indica uma seleção de uma n-tupla (por exemplo enumeração) de escolhas.Em nosso exemplo, podemos optar por definir um Tipo Enumerado que restringirá os possíveis valores atribuídos (ou seja,melhorou segurança de tipo):

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

Uma classe única e genérica de constantes é uma má ideia.As constantes devem ser agrupadas com a classe à qual estão mais relacionadas logicamente.

Em vez de usar variáveis ​​de qualquer tipo (especialmente enums), sugiro que você use métodos.Crie um método com o mesmo nome da variável e faça com que ele retorne o valor que você atribuiu à variável.Agora exclua a variável e substitua todas as referências a ela por chamadas ao método que você acabou de criar.Se você acha que a constante é genérica o suficiente para que você não precise criar uma instância da classe apenas para usá-la, torne o método constante um método de classe.

FWIW, um valor de tempo limite em segundos provavelmente deve ser uma configuração (lida de um arquivo de propriedades ou por meio de injeção como no Spring) e não uma constante.

Qual é a diferença

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 usandoMyGlobalConstants.TIMEOUT_IN_SECS onde quer que precisemos dessa constante.Acho que ambos são iguais.

Eu não chamaria a classe da mesma (além do invólucro) que a constante ...Eu teria no mínimo uma classe de "Configurações", ou "Valores" ou "Constantes", onde residiriam todas as constantes.Se eu tiver um grande número deles, eu os agruparia em classes lógicas constantes (UserSettings, AppSettings, etc.)

Para dar um passo adiante, você pode colocar constantes usadas globalmente em uma interface para que possam ser usadas em todo o sistema.Por exemplo.

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

Mas não o implemente.Basta consultá-los diretamente no código por meio do nome de classe totalmente qualificado.

Para Constantes, Enum é uma escolha melhor IMHO.Aqui está um exemplo

classe pública minhaClasse {

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

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


}

Uma das formas de fazer isso é criando uma classe 'Global' com os valores constantes e fazendo uma importação estática nas classes que precisam de acesso à constante.

static final é a minha preferência, eu usaria apenas um enum se o item fosse realmente enumerável.

eu uso static final para declarar constantes e usar a notação de nomenclatura ALL_CAPS.Já vi alguns casos da vida real em que todas as constantes são agrupadas em uma interface.Algumas postagens consideraram isso uma prática ruim, principalmente porque não é para isso que serve uma interface.Uma interface deve impor um contrato e não deve ser um local para colocar constantes não relacionadas.Colocá-lo junto em uma classe que não pode ser instanciada (por meio de um construtor privado) também é adequado se a semântica constante não pertencer a uma(s) classe(s) específica(s).Sempre coloco uma constante na classe com a qual ela está mais relacionada, porque faz sentido e também é de fácil manutenção.

Enums são uma boa opção para representar um intervalo de valores, mas se você estiver armazenando constantes independentes com ênfase no valor absoluto (por exemplo,TIMEOUT = 100 ms) você pode simplesmente ir para o static final abordagem.

Concordo com o que a maioria diz: é melhor usar enums ao lidar com uma coleção de constantes.Porém, se você estiver programando em Android existe uma solução melhor: Anotação 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();

A anotação IntDef é superior às enums de uma maneira simples: ocupa significativamente menos espaço, pois é simplesmente um marcador de tempo de compilação.Não é uma classe nem possui a propriedade de conversão automática de strings.

Isso é MAU hábito e terrivelmente Prática IRRITANTE citar Joshua Bloch sem compreender o fundamentalismo básico do marco zero.

Eu não li nada de Joshua Bloch, então também

  • ele é um péssimo programador
  • ou as pessoas que até agora o citam (Joshua é o nome de um menino, presumo) estão simplesmente usando seu material como roteiros religiosos para justificar suas indulgências religiosas de software.

Como no fundamentalismo bíblico, todas as leis bíblicas podem ser resumidas por

  • Ame a Identidade Fundamental com todo o seu coração e toda a sua mente
  • Ame o seu próximo como a si mesmo

e assim, da mesma forma, o fundamentalismo da engenharia de software pode ser resumido por

  • dedique-se aos fundamentos do marco zero com todo o seu poder e mente de programação
  • e dedique-se à excelência de seus colegas programadores como faria por si mesmo.

Além disso, entre os círculos fundamentalistas bíblicos, desenha-se um corolário forte e razoável

  • Primeiro AME a si mesmo.Porque se você não se ama muito, então o conceito “ame o próximo como a si mesmo” não tem muito peso, pois “o quanto você se ama” é a linha de referência acima da qual você amaria os outros.

Da mesma forma, se você não se respeita como programador e apenas aceita os pronunciamentos e profecias de algum guru de programação SEM questionar os fundamentos, suas citações e confiança em Joshua Bloch (e similares) não têm sentido.E, portanto, você realmente não teria respeito pelos seus colegas programadores.

As leis fundamentais da programação de software

  • preguiça é a virtude de um bom programador
  • você deve tornar sua vida de programação tão fácil, tão preguiçosa e, portanto, tão eficaz quanto possível
  • você deve tornar as consequências e as entranhas de sua programação tão fáceis, tão preguiçosas e, portanto, tão eficazes quanto possível para seus vizinhos-programadores que trabalham com você e captam suas entranhas de programação.

Constantes de padrão de interface são um mau hábito ???

Sob quais leis de programação fundamentalmente eficaz e responsável este decreto religioso se enquadra?

Basta ler o artigo da Wikipedia sobre constantes de padrão de interface (https://en.wikipedia.org/wiki/Constant_interface) e as desculpas tolas que ele apresenta contra constantes de padrão de interface.

  • E se não houver IDE?Quem diabos, como programador de software, não usaria um IDE?A maioria de nós somos programadores que preferem não ter que provar ter um sobrevivencialismo escético machista evitando o uso de um IDE.

    • Além disso - espere um segundo proponentes da programação microfuncional como um meio de não precisar de um IDE.Espere até ler minha explicação sobre normalização de modelos de dados.
  • Polui o namespace com variáveis ​​não utilizadas no escopo atual?Poderiam ser defensores desta opinião

    • não estão cientes e da necessidade de normalização do modelo de dados
  • Usar interfaces para impor constantes é um abuso de interfaces.Os defensores disso têm o mau hábito de

    • não vendo que “constantes” devem ser tratadas como contrato.E as interfaces são usadas para fazer cumprir ou projetar a conformidade de um contrato.
  • É difícil, senão impossível, converter interfaces em classes implementadas no futuro.Hah ....hmmm ...???

    • Por que você iria querer se envolver em tal padrão de programação como seu sustento persistente?IOW, por que se dedicar a um hábito de programação tão AMBIVALENTE e ruim?

Quaisquer que sejam as desculpas, NÃO HÁ DESCULPA VÁLIDA quando se trata de engenharia de software FUNDAMENTALMENTE EFICAZ para deslegitimar ou geralmente desencorajar o uso de constantes de interface.

Não importa quais foram as intenções originais e os estados mentais dos pais fundadores que elaboraram a Constituição dos Estados Unidos.Poderíamos debater as intenções originais dos pais fundadores, mas tudo o que me importa são as declarações escritas da Constituição dos EUA.E é responsabilidade de cada cidadão dos EUA explorar o fundamentalismo literário escrito, e não as intenções fundadoras não escritas, da Constituição dos EUA.

Da mesma forma, não me importa quais foram as intenções "originais" dos fundadores da plataforma Java e da linguagem de programação para a interface.O que me importa são os recursos eficazes que a especificação Java fornece, e pretendo explorar esses recursos ao máximo para me ajudar a cumprir as leis fundamentais da programação de software responsável.Não me importo se sou percebido como "violando a intenção das interfaces".Eu não me importo com o que Gosling ou alguém Bloch diga sobre a "maneira correta de usar Java", a menos que o que eles digam não viole minha necessidade de cumprir os fundamentos EFICAZMENTE.

O fundamental é a normalização do modelo de dados

Não importa como o seu modelo de dados é hospedado ou transmitido.Quer você use interfaces ou enums ou qualquer outra coisa, relacional ou sem SQL, se você não entende a necessidade e o processo de normalização do modelo de dados.

Devemos primeiro definir e normalizar o modelo de dados de um conjunto de processos.E quando temos um modelo de dados coerente, SOMENTE então podemos usar o fluxo de processo de seus componentes para definir o comportamento funcional e processar blocos de um campo ou domínio de aplicativos.E só então poderemos definir a API de cada processo funcional.

Mesmo as facetas da normalização de dados propostas por EF Codd são agora severamente desafiadas e severamente desafiadas.por exemplo.a sua declaração sobre o 1NF foi criticada como ambígua, desalinhada e demasiado simplificada, tal como o resto das suas declarações, especialmente no advento dos modernos serviços de dados, tecnologia de recompra e transmissão.IMO, as declarações de EF Codd deveriam ser completamente abandonadas e um novo conjunto de declarações mais matematicamente plausíveis deveria ser projetado.

Uma falha flagrante de EF Codd e a causa de seu desalinhamento com a compreensão humana efetiva é sua crença de que dados multidimensionais e de dimensões mutáveis ​​humanamente perceptíveis podem ser percebidos de forma eficiente por meio de um conjunto de mapeamentos bidimensionais fragmentados.

Os fundamentos da normalização de dados

O que EF Codd não conseguiu expressar.

Dentro de cada modelo de dados coerente, esta é a ordem sequencial graduada de coerência do modelo de dados a ser alcançada.

  1. A unidade e a identidade das instâncias de dados.
    • projetar a granularidade de cada componente de dados, em que sua granularidade esteja em um nível onde cada instância de um componente possa ser identificada e recuperada exclusivamente.
    • ausência de alias de instância.isto é, não existe nenhum meio pelo qual uma identificação produza mais de uma instância de um componente.
  2. Ausência de crosstalk de instância.Não existe a necessidade de usar uma ou mais instâncias de um componente para contribuir para a identificação de uma instância de um componente.
  3. A unidade e identidade dos componentes/dimensões dos dados.
    • Presença de suavização de componente.Deve existir uma definição pela qual um componente/dimensão possa ser identificado de forma única.Qual é a definição principal de um componente;
    • onde a definição primária não resultará na exposição de subdimensões ou componentes de membros que não fazem parte de um componente pretendido;
  4. Meio exclusivo de negociação de componentes.Deve existir uma, e apenas uma, definição de remoção de alias de componente para um componente.
  5. Existe uma, e apenas uma, interface de definição ou contrato para identificar um componente pai em um relacionamento hierárquico de componentes.
  6. Ausência de crosstalk de componente.Não existe a necessidade de utilizar um membro de outro componente para contribuir para a identificação definitiva de um componente.
    • Nesse relacionamento pai-filho, a definição de identificação de um pai não deve depender de parte do conjunto de componentes membros de um filho.Um componente membro da identidade de um pai deve ser a identidade completa do filho, sem recorrer à referência a um ou a todos os filhos de um filho.
  7. Previna as aparências bimodais ou multimodais de um modelo de dados.
    • Quando existem duas definições candidatas de um componente, é um sinal óbvio de que existem dois modelos de dados diferentes sendo misturados como um só.Isso significa que há incoerência no nível do modelo de dados ou no nível do campo.
    • Um campo de aplicações deve usar um e apenas um modelo de dados, de forma coerente.
  8. Detecte e identifique mutações de componentes.A menos que você tenha realizado análises estatísticas de componentes de grandes dados, provavelmente não verá ou verá a necessidade de tratar a mutação de componentes.
    • Um modelo de dados pode ter alguns de seus componentes mutados de forma cíclica ou gradual.
    • O modo pode ser rotação de membro ou rotação de transposição.
    • A mutação de rotação de membros pode ser uma troca distinta de componentes filhos entre componentes.Ou onde componentes completamente novos teriam que ser definidos.
    • A mutação transposicional se manifestaria como um membro dimensional se transformando em um atributo, vice-versa.
    • Cada ciclo de mutação deve ser identificado como um modal de dados distinto.
  9. Versionize cada mutação.De forma que você possa extrair uma versão anterior do modelo de dados, quando talvez surja a necessidade de tratar uma mutação do modelo de dados de 8 anos.

Em um campo ou grade de aplicativos de componentes entre serviços, deve haver um e apenas um modelo de dados coerente ou existe um meio para um modelo/versão de dados se identificar.

Ainda estamos perguntando se poderíamos usar constantes de interface?Realmente ?

Há questões de normalização de dados em jogo com mais consequências do que esta questão mundana.SE você não resolver esses problemas, a confusão que você acha que as constantes da interface causam será comparativamente nada.Zero.

A partir da normalização do modelo de dados, você determina os componentes como variáveis, como propriedades, como constantes da interface do contrato.

Em seguida, você determina o que vai para injeção de valor, espaço reservado para configuração de propriedade, interfaces, strings finais, etc.

Se você tiver que usar a desculpa de precisar localizar um componente mais fácil de ditar as constantes da interface, isso significa que você tem o mau hábito de não praticar a normalização do modelo de dados.

Talvez você queira compilar o modelo de dados em uma versão vcs.Que você pode extrair uma versão distintamente identificável de um modelo de dados.

Os valores definidos nas interfaces são totalmente garantidos como não mutáveis.E compartilhável.Por que carregar um conjunto de strings finais de outra classe em sua classe quando tudo que você precisa é desse conjunto de constantes?

Então, por que não publicar um contrato de modelo de dados?Quero dizer, se você consegue gerenciar e normalizar isso de forma coerente, por que não?...

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

Agora posso fazer referência aos rótulos contratados dos meus aplicativos de uma forma como

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

Isso confunde o conteúdo do arquivo jar?Como programador Java, não me importo com a estrutura do jar.

Isso apresenta complexidade para a troca de tempo de execução motivada por osgi?Osgi é um meio extremamente eficiente para permitir que os programadores continuem com seus maus hábitos.Existem alternativas melhores que o osgi.

Ou por que não isso?Não há vazamento das constantes privadas no contrato publicado.Todas as constantes privadas devem ser agrupadas em uma interface privada chamada "Constantes", porque não quero procurar constantes e tenho preguiça de digitar repetidamente "String final privada".

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

Talvez até isso:

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

O único problema com constantes de interface que vale a pena considerar é quando a interface é implementada.

Esta não é a “intenção original” das interfaces?Como se eu me preocupasse com a "intenção original" dos pais fundadores ao elaborar a Constituição dos EUA, e não com a forma como a Suprema Corte interpretaria as cartas escritas da Constituição dos EUA ???

Afinal, moro na terra dos livres, dos selvagens e do lar dos corajosos.Seja corajoso, seja livre, seja selvagem - use a interface.Se meus colegas programadores se recusarem a usar meios de programação eficientes e preguiçosos, sou obrigado pela regra de ouro a diminuir minha eficiência de programação para me alinhar com a deles?Talvez devesse, mas essa não é uma situação ideal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top