it-swarm-pt.tech

Qual é a melhor maneira de implementar em Java?

Eu vi exemplos como este:

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

e supostamente eu poderia ter uma classe Constants para envolver constantes, declarando-as como final estático. Eu não conheço praticamente nenhum Java e estou imaginando se essa é a melhor maneira de criar constantes.

373
mk.

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

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

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

Eu recomendo altamente não colocar suas constantes em suas próprias classes ou interfaces.

Como uma nota lateral: Variáveis ​​declaradas como final e mutáveis ​​ainda podem ser alteradas; no entanto, 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).

403
jjnguy

Eu recomendaria altamente contra ter uma única classe de constantes. Pode parecer uma boa ideia na época, mas quando os desenvolvedores se recusam a documentar constantes e a classe cresce para abranger mais de 500 constantes que não são relacionadas entre si (sendo relacionadas a aspectos completamente diferentes da aplicação), geralmente se transforma no arquivo de constantes sendo 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 se referir a enums, não a valores constantes, para essas constantes. Você pode declarar um enum similar a como você declara uma classe. Os enums são talvez o recurso mais útil (e, possivelmente, único) do Java 5+.
  • Se você tiver constantes que sejam 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. Desta forma, as subclasses podem acessar estes valores constantes (e se outras classes acessam-nas via público, as constantes não são válidas apenas para uma classe em particular ... o que significa que as classes externas que usam esta constante podem ser muito fortemente acopladas à classe contendo a constante)
  • Se você tem uma interface com comportamento definido, mas valores retornados ou valores de argumentos devem ser particulares, é perfeitamente aceitável definir constantes nessa interface para que outros implementadores tenham acesso a elas. No entanto, evite criar uma interface apenas para manter constantes: ela pode se tornar tão ruim quanto uma classe criada apenas para manter constantes.
235
MetroidFan2002

É BAD PRACTICE usar interfaces apenas para manter constantes (chamado 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ê deverá adicioná-las à classe ou interface. Por exemplo, todas as classes primitivas numéricas em caixa, como Integer e Double, exportam constantes MIN_VALUE e MAX_VALUE. Se as constantes forem melhor visualizadas como membros de um tipo enumerado, você deverá exportá-las com um tipo enum. Caso contrário, você deve exportar as constantes com uma classe de utilitário não instanciável.

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 consistindo de letras maiúsculas, com palavras separadas por sublinhados. É fundamental que esses campos contenham valores primitivos ou referências a objetos imutáveis.

120
Marcio Aguiar

Em Java eficaz (2ª edição), é recomendável usar enums em vez de ints estáticos para constantes.

Há um bom writeup em enums em Java aqui: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html

Observe que no final desse artigo a pergunta é:

Então, quando você deve usar enums?

Com uma resposta de:

Sempre que precisar de um conjunto fixo de constantes

36
shelfoo

Apenas evite usar uma interface:

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

public class NeddsConstant implements MyConstants {

}

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

21
stimpy

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 "objeto orientadamente" quanto a mim.

19
albus.ua

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 faça referência a ela.

Se depois você alterar a classe 'Constantes' e não fizer uma re-compilação em outras classes que fazem referência a essa classe, você terá uma combinação de valores antigos e novos sendo usados.

Em vez de pensar nelas como constantes, pense nelas como parâmetros de configuração e crie uma classe para gerenciá-las. Os valores não são finais e até consideram o uso de getters. No futuro, quando você determinar que alguns desses parâmetros devem ser configuráveis ​​pelo usuário ou pelo administrador, será muito mais fácil fazer isso.

17
Kevin Day

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

Em vez disso, as constantes devem entrar na classe que "as possui". Você tem uma constante chamada TIMEOUT? Ele provavelmente deve entrar em sua classe Communications () ou Connection (). MAX_BAD_LOGINS_PER_HOUR? Vai para o usuário (). E assim por diante.

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

13
Yann Ramin

Esse é o caminho certo a seguir.

Geralmente as constantes são não mantidas em classes "Constantes" separadas porque elas não são detectáveis. Se a constante é relevante para a classe atual, mantê-los lá ajuda o próximo desenvolvedor.

6
Jason Cohen

Concordo que usar uma interface não é o caminho a percorrer. Evitar este padrão tem seu próprio item (# 18) no Bloch --- Effective Java .

Um argumento que Bloch faz 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á-los expõe esse detalhe de implementação em sua API exportada.

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

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

Se você estiver usando uma versão anterior à 1.5, ainda poderá retirar enumerações de tipos seguros usando classes Java normais. (Veja este site para mais sobre isso).

5
Rob Dickerson

Que tal uma enumeração?

5
Sébastien D.

Eu prefiro usar getters ao invés 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.

Uma vantagem é que, se o seu programa ultrapassa a constante - você acha que precisa ser configurável -, você pode simplesmente mudar como o getter retorna a constante.

O outro benefício é que, para modificar a constante, você não precisa recompilar tudo o 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 ela.

5
big_peanut_horse

Com base nos comentários acima, acho que essa é uma boa abordagem para alterar a classe de constante global antiquada (com variáveis ​​finais estáticas públicas) para seu equivalente em enumeração de uma maneira como esta:

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 eu posso referenciá-los como:

Constants.StringConstant.DB_Host
4
Lorand Bendig

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

3
Bradley Harris

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

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 espera-se que as interfaces sejam implementadas. Isso não parece engraçado:

String myConstant = IMyInterface.CONSTANTX;

Em vez disso, eu escolheria entre algumas maneiras diferentes, com base em alguns pequenos trade-offs, 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
2
djangofan

Qual é a melhor maneira de implementar constantes em Java?

ma abordagem que devemos evitar: usando interfaces para definir constantes.

Criar uma interface especificamente para declarar constantes é realmente a pior coisa: ela anula o motivo pelo qual as interfaces foram projetadas: definindo contrato (s) de método (s).

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


Para simplificar, temos 4 abordagens válidas.

Com o campo static final String/Integer:

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

Com Java 5 enum:

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

TLDR: Qual é o melhor caminho e onde localizar as constantes?

Na maioria dos casos, o caminho enum é provavelmente mais fino que o modo static final String/Integer e pessoalmente eu acho que o modo static final String/Integer deve ser usado somente se tivermos boas razões para não usar enums.
E sobre onde devemos declarar os valores constantes, a idéia é pesquisar se existe uma única classe existente que possui uma coesão funcional específica e forte com valores constantes. Se encontrarmos essa classe, devemos usá-lo como o detentor das constantes. Caso contrário, a constante deve ser associada a nenhuma classe específica.


static final String/static final Integer VERSUS enum

O uso de enums é realmente uma maneira de considerar fortemente.
Enums têm uma grande vantagem sobre o campo constante String ou Integer.
Eles definiram uma restrição de compilação mais forte. Se você definir um método que usa o enum como parâmetro, você só pode passar um valor de 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 nos campos static final String/static final Integer.

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

public class MyClass{

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

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

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

Você pode invocá-lo desta maneira:

process(MyClass.ONE_CONSTANT);

ou

process(MyClass.ANOTHER_CONSTANT);

Mas nenhuma restrição de compilação impede que você a invoque dessa maneira:

process("a not defined constant value");

Você teria o erro apenas em tempo de execução e somente se você fizer de cada vez uma verificação no valor transmitido.

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

Por exemplo, aqui dois valores definidos em uma classe enum (assim constante fora da caixa):

public enum MyEnum {

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

    private String value;

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

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

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

Você pode invocá-lo desta maneira:

process(MyEnum.ONE_CONSTANT);

ou

process(MyEnum.ANOTHER_CONSTANT);

Mas a compilação nunca permitirá que você a invoque dessa maneira:

process("a not defined constant value");

Onde devemos declarar as constantes?

Se o seu aplicativo contiver uma única classe existente que possui uma coesão funcional forte e específica com os valores constantes, o 1) e o 2) parecerão mais intuitivos.
Geralmente, facilita o uso das constantes se estas forem declaradas na classe principal que as manipulam ou que tem um nome muito natural para adivinhar que vamos encontrá-las dentro.

Por exemplo, na biblioteca JDK, os valores da constante exponencial e pi são declarados em uma classe que declara não apenas declarações de 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 da classe Math. Assim, eles podem encontrar constantes com bastante facilidade e também podem lembrar onde E e PI são definidos de uma maneira muito natural.

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

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

Muitas classes declaradas em Java.util.concurrent as usam: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... e realmente nenhuma delas parece mais apropriada para conter o enum.

2
davidxxx

FWIW, um valor de tempo limite em segundos provavelmente deve ser uma configuração (leia a partir de um arquivo de propriedades ou através de injeção como no Spring) e não uma constante.

1
Tim Howland

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 usando MyGlobalConstants.TIMEOUT_IN_SECS sempre que precisarmos dessa constante. Eu acho que ambos são iguais.

1
chandrayya

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

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 retorne o valor atribuído à variável. Agora, exclua a variável e substitua todas as referências a ela por chamadas para o método recém-criado. 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, então torne o método constant um método de classe.

1
ab

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

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

Existem inúmeras aplicações em que o valor de uma constante indica uma seleção de um n-Tuple (por exemplo, enumeração) das opções. Em nosso exemplo, podemos optar por definir um tipo enumerado que restringirá os possíveis valores atribuídos (ou seja, melhorados type-safety):

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

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

0
Joel Martinez

static final é minha preferência, eu usaria somente um enum se o item fosse de fato enumerável.

0
wulfgarpro

É hábito BAD e prática terrivelmente irritante citar Joshua Bloch sem entender o fundamentalismo básico do ground-zero.

Eu não li nada Joshua Bloch, então ou

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

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

  • Ame a Identidade Fundamental com todo seu coração e toda sua mente
  • Ame seu vizinho como você mesmo

e assim similarmente o fundamentalismo de engenharia de software pode ser resumido por

  • dedicar-se aos fundamentos do ponto zero com toda a sua programação e mente
  • e dedicar-se à excelência de seus colegas programadores como você faria por si mesmo.

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

  • Primeiro AME a si mesmo. Porque se você não se ama muito, então o conceito de "amar seu próximo como a si mesmo" não tem muito peso, já que "quanto você se ama" é a linha de dados 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 programa guru-nath sem questionar os fundamentos, suas citações e sua confiança em Joshua Bloch (e similares) não têm sentido. E, portanto, você realmente não teria respeito por 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, preguiçosa e, portanto, tão eficaz quanto possível
  • você deve tornar as conseqüências e entranhas de sua programação tão fáceis, preguiçosas e, portanto, tão eficazes quanto possível para seus programadores-vizinhos que trabalham com você e pegam suas entranhas de programação.

As constantes do padrão de interface são um mau hábito ???

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

Apenas leia o artigo da wikipedia sobre as constantes do padrão de interface ( https://en.wikipedia.org/wiki/Constant_interface ), e o bobo desculpa-se contra as constantes do padrão de interface.

  • Whatif-No IDE? Quem na terra como programador de software não usaria um IDE? A maioria de nós é programadora que prefere não ter que provar um survivalisticismo aescético machista para evitar o uso de uma IDE.

    • Também - espere um segundo proponente da programação micro-funcional como um meio de não precisar de um IDE. Espere até você ler minha explicação sobre a normalização do modelo de dados.
  • Polui o namespace com variáveis ​​não usadas no escopo atual? Podem ser defensores dessa opinião

    • não estão cientes e a necessidade de normalização do modelo de dados
  • Usando interfaces para impor constantes é um abuso de interfaces. Os proponentes de tal têm um mau hábito de

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

    • Por que você gostaria de se envolver em tal padrão de programação como seu meio de subsistência persistente? IOW, por que se dedicar a tal hábito de programação ruim e ambivalente?

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

Não importa quais foram as intenções originais e os estados mentais dos pais fundadores que criaram a Constituição dos Estados Unidos. Poderíamos debater as intenções originais dos pais fundadores, mas tudo o que me interessa são as declarações escritas da Constituição dos EUA. E é responsabilidade de todo cidadão norte-americano 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 importo com as intenções "originais" dos fundadores da plataforma Java e da linguagem de programação para a interface. O que me interessa são os recursos eficazes que a especificação Java fornece, e pretendo explorar ao máximo esses recursos para me ajudar a cumprir as leis fundamentais da programação de software responsável. Eu não me importo se eu sou percebido como "violar a intenção de interfaces". Eu não me importo com o que Gosling ou alguém Bloch diz sobre a "maneira correta de usar Java", a menos que o que eles dizem não viole minha necessidade de cumprir os fundamentos EFICAZES.

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

Não importa como o seu modelo de dados é hospedado ou transmitido. Se você usa interfaces ou enums ou whatevernots, relacionais ou não-SQL, se você não entender 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, APENAS podemos usar o fluxo de processo de seus componentes para definir o comportamento funcional e o processo bloqueia um campo ou domínio de aplicativos. E só então podemos definir a API de cada processo funcional.

Até mesmo as facetas da normalização de dados, como proposto por EF Codd, agora são severamente desafiadas e severamente desafiadas. por exemplo. sua declaração sobre a 1NF tem sido criticada como ambígua, desalinhada e simplificada, assim como o resto de suas declarações, especialmente no advento dos modernos serviços de dados, repo-tecnologia e transmissão. IMO, as declarações EF Codd devem ser completamente descartadas e um novo conjunto de declarações matematicamente mais plausíveis deve ser projetado.

Uma falha flagrante da EF Codd e a causa de seu desalinhamento para a compreensão humana efetiva é a sua crença de que os dados multidimensionais de dimensões mutáveis ​​e humanamente perceptíveis podem ser percebidos eficientemente através de um conjunto de mapeamentos bidimensionais fragmentados.

Os fundamentos da normalização de dados

O que a EF Codd não conseguiu expressar.

Dentro de cada modelo de dados coerente, é a ordem sequencial graduada da 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 está em um nível em que cada instância de um componente pode ser identificada e recuperada exclusivamente.
    • ausência de aliasing 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 outras 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 desprovimento de alias de componentes. Deve existir uma definição em que um componente/dimensão pode ser identificado de forma única. Qual é a definição primária 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. Meios exclusivos de dealiasing de componentes. Deve existir uma, e apenas uma, definição de suavização 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 usar um membro de outro componente para contribuir para a identificação definitiva de um componente.
    • Em tal relacionamento pai-filho, a definição de identificação de um pai não deve depender de parte do conjunto de componentes de membro de um filho. Um componente membro da identidade de um pai deve ser a identidade completa da criança sem recorrer à referência a qualquer um ou a todos os filhos de um filho.
  7. Preferência de aparências bi-modais 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. Isso significa que há incoerência no nível do modelo de dados ou no nível do campo.
    • Um campo de aplicativos deve usar um e somente um modelo de dados, de forma coerente.
  8. Detecte e identifique a mutação do componente. A menos que você tenha feito uma análise de componentes estatísticos de dados enormes, você 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 mutáveis ​​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 poderia 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 que se transforma em um atributo, vice-versa.
    • Cada ciclo de mutação deve ser identificado como um modal de dados distinto.
  9. Versionize cada mutação. Tal que você pode retirar uma versão anterior do modelo de dados, quando talvez surja a necessidade de tratar uma mutação de 8 anos do modelo de dados.

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

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

Há questões de normalização de dados em jogo mais consequentes do que essa questão mundana. Se você não resolver esses problemas, a confusão que você acha que as constantes de interface causam é comparativamente nada. Zilch.

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 valor da injeção de valor, a colocação da propriedade na configuração, as interfaces, as seqüências finais, etc.

Se você tiver que usar a desculpa de precisar localizar um componente mais fácil de ditar contra constantes de interface, isso significa que você tem o péssimo 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 do vcs. Que você pode extrair uma versão distintamente identificável de um modelo de dados.

Valores definidos em interfaces são completamente garantidos para serem não-mutáveis. E compartilhável. Por que carregar um conjunto de strings finais em sua classe de outra classe quando tudo que você precisa é esse conjunto de constantes?

Então, por que não publicar um contrato de modelo de dados? Quero dizer, se você conseguir administrar e normalizar coerentemente, 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 maneira a

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 troca de tempo de execução motivada por osgi? Osgi é um meio extremamente eficiente para permitir que os programadores continuem em seus maus hábitos. Existem alternativas melhores do que osgi.

Ou porque não isso? Não há vazamento das constantes privadas para o contrato publicado. Todas as constantes privadas devem ser agrupadas em uma interface privada chamada "Constantes", porque eu não quero ter que procurar por 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 importasse com a "intenção original" dos pais fundadores em elaborar a Constituição dos EUA, ao invés de como a Suprema Corte interpretaria as cartas escritas da Constituição dos EUA?

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

0
Blessed Geek

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

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

Mas não implemente isso. Basta se referir a eles diretamente no código através do nome completo da classe.

0
Andrew Harmel-Law

Eu uso static final para declarar constantes e ir com a notação de nomenclatura ALL_CAPS. Tenho visto algumas instâncias da vida real em que todas as constantes são agrupadas em uma interface. Alguns posts justamente chamam isso de má prática, 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 em uma classe que não pode ser instanciada (por meio de um construtor privado) também é bom se a semântica constante não pertencer a uma classe específica ( es). Eu sempre coloco uma constante na classe com a qual ela está mais relacionada, porque isso faz sentido e também é facilmente passível de manutenção.

As 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), basta ir para a abordagem static final.

0
bincob

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

classe pública 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
mmansoor

Eu concordo com o que a maioria está dizendo, é melhor usar enums quando se lida com uma coleção de constantes. No entanto, se você estiver programando no Android, há uma solução melhor: 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();

A anotação IntDef é superior a enums de uma maneira simples, leva 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.

0
Quinn Turner

Uma das maneiras de fazer isso é criar uma classe 'Global' com os valores constantes e fazer uma importação estática nas classes que precisam acessar a constante.

0
Javamann