Estou trabalhando em um aplicativo com muitas constantes. Na última revisão de código, constatou-se que as constantes estão muito dispersas e devem ser organizadas em um único arquivo de constantes "principais". A discordância é sobre como organizá-los. A maioria considera que o uso do nome constante deve ser bom o suficiente, mas isso levará a um código parecido com este:
public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";
Acho esse tipo de convenção de nomenclatura complicado. Eu pensei que poderia ser mais fácil usar a classe aninhada pública e ter algo como isto:
public class IntegrationSystemConstants
{
public class CreditCard
{
public static final String UI_EXPIRY_MONTH = "3524";
public static final String UI_ACCOUNT_ID = "3524";
...
}
public class BankAccount
{
public static final String UI_ACCOUNT_ID = "9987";
...
}
}
Essa ideia não foi bem recebida porque era "muito complicada" (não obtive muitos detalhes sobre por que isso pode ser muito complicado). Eu acho que isso cria uma divisão melhor entre grupos de constantes relacionadas e o preenchimento automático facilita a localização também. Eu nunca vi isso feito, então estou me perguntando se essa é uma prática aceita ou se há melhores razões para que isso não deva ser feito.
fonte
Respostas:
Não concordo com nenhuma das duas propostas.
As constantes devem estar em suas classes pertinentes , não em uma classe todo-constante em qualquer uma das duas formas propostas.
Não deve haver classes / interfaces somente constantes.
Uma classe
CreditCard
(não uma classe interna) deve existir. Esta classe / interface possui métodos relativos a cartões de crédito, bem como as constantesUI_EXPIRY_MONTH
eUI_ACCOUNT_ID
.Deve existir uma classe / interface
BankAccount
(não uma classe interna). Essa classe / interface possui métodos relativos a contas bancárias e também constantesUI_ACCOUNT_ID
.Por exemplo, na API Java, toda classe / interface tem suas constantes. Eles não estão em uma classe / interface de Constantes com centenas de constantes, agrupadas em classes internas ou não.
Por exemplo, essas constantes pertinentes aos conjuntos de resultados estão na interface
ResultSet
:Essa interface possui assinaturas de método relativas aos conjuntos de resultados e as classes de implementação implementam esse comportamento. Eles não são meros detentores de constantes.
Essas constantes pertinentes às ações da interface do usuário estão na interface
javax.swing.Action
:As classes de implementação têm comportamento em relação às ações da interface do usuário, não são meros detentores constantes.
Conheço pelo menos uma interface de "constantes" (
SwingConstants
) sem métodos, mas ela não possui centenas de constantes, apenas algumas, e todas estão relacionadas às direções e posições dos elementos da interface do usuário:Penso que apenas classes constantes não são um bom design de OO.
fonte
Esta é a solução 100% errada para o problema das constantes serem "difíceis de encontrar". É um erro fundamental (infelizmente comumente cometido por programadores) agrupar coisas por critérios técnicos, como constantes, enumerações ou interfaces.
Exceto pelas arquiteturas de camada, as coisas devem ser agrupadas por seu domínio e constantes ainda mais, pois são elementos de nível muito baixo. As constantes devem fazer parte das classes ou interfaces que as usam como parte de sua API. Se você não conseguir encontrar um lugar natural para morar, precisará limpar o design da API.
Além disso, um único arquivo de constantes enormes reduz a velocidade de desenvolvimento em Java, porque as constantes são incorporadas às classes que os usam em tempo de compilação; portanto, qualquer alteração força a recompilação de todos esses arquivos e tudo o que depende deles. Se você tiver um arquivo com constantes que são usadas em todos os lugares, perderá amplamente o benefício da compilação incremental: observe o Eclipse travar por 15 minutos, pois recompila todo o projeto para cada alteração nesse arquivo. E como esse arquivo contém todas as constantes usadas em qualquer lugar, você será alterado com bastante frequência. Sim, estou falando por experiência pessoal.
fonte
Você está certo. Sua sugestão permite que um programador
import static Constants.BankAccount.*
elimine inúmeras repetições de 'BANKACCOUNT_'. A concatenação é um mau substituto para o escopo real. Dito isto, não tenho muita esperança de que você mude a cultura da equipe. Eles têm noção de práticas adequadas e provavelmente não mudarão, mesmo que você mostre a eles 100 especialistas que dizem estar errados.Também estou me perguntando por que você tem um único arquivo 'Constantes'. Essa é uma prática muito ruim, a menos que essas constantes estejam relacionadas de alguma forma e sejam muito estáveis. Mais tipicamente, torna-se um tipo de classe de pia de cozinha que muda constantemente e depende de tudo.
fonte
Ambas as abordagens funcionam, e é isso que é importante no final do dia.
Dito isso, sua abordagem é comum o suficiente para ser considerada um padrão ou, com mais precisão, uma melhoria suficientemente boa sobre o antipadrão da interface constante . Não vejo o que é complicado, mas é uma discussão que você deve ter com sua equipe.
fonte
Um dos desafios da longa lista de constantes é encontrar a constante "correta" a ser usada. Invariavelmente, alguém insere uma constante no final da linha em vez de adicioná-la ao grupo ao qual pertencia.
O que traz outro ponto a ser discutido com sua equipe - já existe uma categorização de fato das constantes através de seus nomes. Portanto, não deve ser uma grande mudança para eles do estado atual para o que você está propondo. O uso do preenchimento automático facilita ainda mais as pesquisas constantes.
De qualquer forma, sua sugestão ajuda a desencorajar o uso da constante "errada", mesmo que ela se encaixe em uma situação específica. Ao agrupar as constantes em uma classe representativa, isso incentivará os desenvolvedores a pensarem se deveriam usá-la. Por exemplo, se eu
CreditCard.SomeConstant
usar para uso geral, realmente me pergunto por que não existe umGeneral.SomeConstant
para essa situação.Estive em projetos com quantidades monstruosas de constantes e preferia ter o método que você está sugerindo. É mais limpo, mais direto e ajuda a evitar o uso inadvertido.
fonte
Faço isso ocasionalmente (em C #), principalmente se precisar programar / analisar uma estrutura XML conhecida e fixa ou algo aninhado e pesado de forma semelhante ... por exemplo, um analisador de bloco de configuração personalizado.
Eu construo uma estrutura de classe aninhada que corresponde à estrutura hierárquica do XML com os nomes de classe correspondentes aos elementos que contêm uma propriedade const string "ElementName" e uma propriedade semelhante correspondente a cada Atributo (se houver).
Isso facilita muito a programação no Xml correspondente.
fonte