Em nossas aplicações majoritariamente grandes, geralmente temos apenas alguns locais para "constantes":
- Uma classe para GUI e concorrentes internos (títulos da guia, títulos da caixa de grupo, fatores de cálculo, enumerações)
- Uma classe para tabelas e colunas de banco de dados (esta parte é código gerado) mais nomes legíveis para eles (atribuídos manualmente)
- Uma classe para mensagens de aplicativos (log, caixas de mensagens etc.)
As constantes são geralmente separadas em estruturas diferentes nessas classes. Em nossos aplicativos C ++, as constantes são definidas apenas no arquivo .h e os valores são atribuídos no arquivo .cpp.
Uma das vantagens é que todas as strings etc. estão em um local central e todos sabem onde encontrá-las quando algo deve ser alterado.
Isso é especialmente algo que os gerentes de projeto parecem gostar quando as pessoas vão e vêm e, dessa forma, todos podem mudar coisas tão triviais sem precisar se aprofundar na estrutura do aplicativo.
Além disso, você pode alterar facilmente o título de caixas de grupo / páginas de guias semelhantes, etc., de uma só vez. Outro aspecto é que você pode imprimir essa classe e entregá-la a um não programador que pode verificar se as legendas são intuitivas e se as mensagens para o usuário são muito detalhadas ou muito confusas, etc.
No entanto, vejo algumas desvantagens:
- Cada classe é fortemente acoplada às constantes
- Adicionar / Remover / Renomear / Mover uma constante requer recompilação de pelo menos 90% do aplicativo (Nota: Alterar o valor não, pelo menos para C ++). Em um de nossos projetos C ++ com 1500 classes, isso significa cerca de 7 minutos de tempo de compilação (usando cabeçalhos pré-compilados; sem eles, são cerca de 50 minutos) mais 10 minutos de vinculação a determinadas bibliotecas estáticas.
- A criação de uma versão com velocidade otimizada por meio do Visual Studio Compiler leva até 3 horas. Não sei se a enorme quantidade de relações de classe é a fonte, mas pode muito bem ser.
- Você é levado a seqüências temporariamente codificadas diretamente no código, porque deseja testar algo muito rapidamente e não deseja esperar 15 minutos apenas para esse teste (e provavelmente todos os subsequentes). Todo mundo sabe o que acontece com os pensamentos "Eu vou consertar isso depois".
- Reutilizar uma classe em outro projeto nem sempre é fácil (principalmente devido a outros acoplamentos apertados, mas o manuseio de constantes não facilita).
Onde você armazenaria constantes assim? Que argumentos você levaria para convencer seu gerente de projeto de que existem melhores conceitos que também cumprem as vantagens listadas acima?
Sinta-se à vontade para fornecer uma resposta específica ou independente de C ++.
PS: Eu sei que essa pergunta é meio subjetiva, mas sinceramente não conheço nenhum lugar melhor do que este site para esse tipo de pergunta.
Atualização sobre este projeto
Tenho novidades sobre o tempo de compilação:
Após as postagens de Caleb e gbjbaanb, divido meu arquivo de constantes em vários outros arquivos quando tive tempo. Também acabei dividindo meu projeto em várias bibliotecas, o que agora era possível muito mais fácil. Compilar isso no modo de liberação mostrou que o arquivo gerado automaticamente que contém as definições do banco de dados (tabela, nomes de colunas e mais - mais de 8000 símbolos) e cria certos hashes causou enormes tempos de compilação no modo de liberação.
Desativar o otimizador do MSVC para a biblioteca que contém as constantes do banco de dados agora nos permitiu reduzir o tempo total de compilação do seu projeto (vários aplicativos) no modo de liberação de até 8 horas para menos de uma hora!
Ainda precisamos descobrir por que a MSVC tem dificuldade em otimizar esses arquivos, mas, por enquanto, essa mudança alivia muita pressão, pois não precisamos mais confiar apenas nas versões noturnas.
Esse fato - e outros benefícios, como acoplamento menos rígido, melhor reutilização etc. - também mostraram que gastar tempo dividindo as "constantes" não era uma má idéia, afinal ;-)
Update2
Como essa pergunta ainda recebe alguma atenção:
Aqui está o que tenho feito nos últimos anos:
Coloque todas as constantes, variáveis etc. exatamente no escopo relevante: se você usar uma constante apenas em um único método, não há problema em defini-la nesse método. Se uma única classe estiver interessada nela, deixe-a como um detalhe de implementação privada dessa classe. O mesmo se aplica ao espaço para nome, módulo, projeto, escopo da empresa. Eu também uso o mesmo padrão para funções auxiliares e similares. (Isso pode não se aplicar 100% se você desenvolver uma estrutura pública.)
Isso aumenta a capacidade de reutilização, testabilidade e capacidade de manutenção em um nível em que você gasta menos tempo compilando (pelo menos em C ++), mas também menos tempo em correções de bugs, o que lhe dá mais tempo para o desenvolvimento de novos recursos. Ao mesmo tempo, o desenvolvimento desses recursos será mais rápido, pois você poderá reutilizar mais códigos com mais facilidade. Isso supera qualquer vantagem que o arquivo de constantes centrais possa ter por uma magnitude.
Dê uma olhada especialmente no Princípio de Segregação de Interface e no Princípio de Responsabilidade Única, se você quiser saber mais.
Se você concorda, avalie a resposta de Caleb, pois essa atualização é basicamente uma visão mais geral do que ele disse.