Como gerenciar as constantes em vários idiomas?

13

Eu tenho uma situação em que apoio o que é funcionalmente a mesma biblioteca em vários idiomas. Muitas vezes, há constantes que precisam ser compartilhadas entre elas (por exemplo, chaves de nome de campo json ou códigos de erro).

A maneira como atualmente faço isso é ter código que define as constantes em cada idioma.

O problema vem na manutenção. Se eu adicionar um novo código de erro, preciso atualizá-lo manualmente em todas as bibliotecas. Enquanto isso é bom para alguns, torna-se tedioso se eu tiver que dizer 5 sdks para atualizar. Seria bom ter uma única fonte de verdade para elas também.

Pensei em algum tipo de arquivo de configuração, mas ele precisa ser incluído em todos os pacotes implantados, o que adiciona complexidade ao nosso processo de compilação / liberação.

Existe uma maneira melhor de lidar com a manutenção de constantes compartilhadas entre vários idiomas?

enderland
fonte
Sua abordagem é boa, enderland. Eu estava tentando encontrar uma solução melhor para redefinição, porque muitas vezes vários clientes consomem APIs que eu programo e realmente não há uma solução elegante. A redefinição de constantes ainda é a mais direta.
Andy Andy
5
@DavidPacker não não não, você deveria ter uma solução realmente elegante para mim. Não me diga que isso é o melhor que existe! :-)
enderland
1
Eu estava questionando minhas escolhas, mas depois percebi que as constantes deveriam ser constantes. Eles são previsíveis porque são constantes. Armazenando-os em um JSON ou qualquer outro formato geralmente analisável, eles não são mais constantes. Um exemplo típico no meu processo de trabalho é um objeto de notificação que contém um typeatributo para identificação da estrutura ao transferi-lo pela conexão. Com isso, os clientes móveis definem apenas constantes (tipos) que eles entendem no momento e ignoram quaisquer tipos desconhecidos. A definição dinâmica causaria muitos problemas.
Andy Andy
Você precisa de uma tabela de tabelas que mapeie para linhas de constantes de tabelas de idiomas.
johnny

Respostas:

10

Embora eu ache que sua abordagem atual seja provavelmente a mais simples e direta, aqui estão algumas idéias alternativas:

  • Extraia suas constantes (e talvez modelos) para um pacote diferente que seja compilado de forma cruzada em todos os seus idiomas. Você pode conseguir compilar a biblioteca inteira, mas isso pode resultar em uma quantidade substancial de problemas. Apenas as constantes de compilação cruzada devem ser simples o suficiente para que não haja tantos problemas. Você pode publicar seu pacote de constantes e depender dele em suas bibliotecas específicas de idioma. Haxe provavelmente pode fazê-lo. Essa abordagem é boa porque você ainda terá a verificação em tempo de compilação (para idiomas compilados)
  • Armazene a configuração em um serviço central. Por exemplo, serviços da Web soap possuem o WSDL ( Web Service Description Language ) e os serviços REST têm o WADL ( Web Application Description Language ) que descreve as operações e as mensagens do serviço. Também existem serviços de configuração centralizados genéricos, como o Spring Cloud Config
  • Arquivo de configuração. Sei que você já sugeriu, mas acho que não precisa complicar muito o processo de criação / lançamento. Coloque seu arquivo de configuração em um projeto de compilação separado (onde você pode testá-lo). Publique o projeto nos repositórios de pacotes específicos para todos os idiomas (Maven, Nuget, NPM etc.) e, em suas bibliotecas específicas para o idioma, você poderá depender do pacote. Isso não deve ser mais complexo do que ter um projeto adicional em seu pipeline de construção.
  • Como o RubberDuck sugeriu, a geração de código é uma boa alternativa à compilação cruzada. Você pode gerar definições constantes para cada idioma usando uma configuração comum.
Samuel
fonte
5
A geração de código @RubberDuck parece interessante (principalmente para um dos meus casos de uso tangencial, que já envolve um gerador de código).
Enderland
3

Ótima pergunta! Eu tenho exatamente a mesma questão; minhas constantes são essencialmente: quais idiomas são suportados nos meus aplicativos e informações adicionais sobre esses idiomas no que se refere à funcionalidade do aplicativo.

Infelizmente, a melhor coisa que eu encontrei (como você encontrou) é simplesmente redefinir constantes para cada idioma, como você está fazendo atualmente (eu sei, você definitivamente queria ouvir isso ).

Obviamente parece errado, porque é o oposto de DRY ( WET ?? ). No entanto, as constantes devem mudar com tanta frequência que os 5 a 10 minutos de redefini-las para cada idioma realmente não me incomodam. No final do dia, pequenos problemas com alguma solução 'elegante', como configuração compartilhada ou geração de código, podem levar horas ou dias para serem resolvidos, então o que realmente é ganho? A complexidade adicionada com o risco de algo dar errado que poderia exigir um esforço adicional para corrigir não é algo com o qual eu quero lidar.

Além disso, se o seu aplicativo tiver tantas constantes que redefini-las por idioma quando você as adiciona ou altera, leva um tempo significativo, é possível que você tenha um cheiro de código mais significativo para lidar e, nesse ponto, convém ativar para algo mais complexo.

Resumindo, redefini-los para cada idioma tem sido minha melhor solução, e ainda tenho que pensar em algo mais SECO que não tenha mais fatores de risco do que gostaria de lidar.

Uma coisa a fazer definitivamente , porém, é garantir que suas constantes sejam bem documentadas de maneira generalizada (e independente de idioma) (temos um repositório de documentos da empresa com especificações, documentos diversos, documentos da 'prancheta' etc. etc., onde mantemos esse documento). Além disso, verifique se você possui mecanismos para manter suas definições sincronizadas. Esse é um problema tão grande com a abordagem de duplicação quanto você terá, exceto por uma pequena quantidade de sofrimento psicológico causado pela duplicação intencional de código. Mas, no final, suas mudanças constantes devem ser muito deliberadas e pouco frequentes , portanto os problemas de sincronicidade devem ser essencialmente nulos.


Também devo mencionar que, ao longo dos anos, vi portos multilíngues de várias bibliotecas (cansados ​​demais para lembrar o que são no momento) escritos pelo mesmo grupo que invariavelmente tem constantes definidas nos próprios idiomas. Nenhuma configuração compartilhada, nenhuma geração de código (exceto as bibliotecas cliente da API do Google ... mas vamos lá, o Google tem os recursos para permitir essa complexidade). Então acho que atingimos uma parede de tijolos nessa. Talvez alguém venha a criar uma biblioteca para lidar com esse problema;)

Chris Cirefice
fonte
0

Felizmente, o núcleo da sua biblioteca está escrito em um idioma e as outras bibliotecas usam o FFI ( https://en.wikipedia.org/wiki/Foreign_function_interface ) para chamar a biblioteca principal. Isso lhe daria o local central para fornecer uma API para publicar as constantes e definições. Dessa forma, tudo é independente dentro da biblioteca. Estou apenas mencionando isso, pois parece não estar incluído na resposta de Samuel.

Eu acho que realmente depende da capacidade da sua base de usuários. São capazes o suficiente para lidar com a passagem de outro arquivo de configuração? Eles são capazes de configurar um novo serviço? Para a grande maioria dos usuários que eu tenho suporte, eu gostaria que tudo fosse independente - desta forma, os usuários não precisariam pensar nisso.

Robert Baron
fonte
1
Hopefully, the core of you library is written in one language, and the other libraries use FFI Infelizmente, temos bibliotecas para o cliente da Web e o código do servidor (em vários idiomas), então ... não seria trivial a execução (e provavelmente uma vulnerabilidade de segurança se pudéssemos no aplicativo da Web).
Enderland
Sugiro que você melhore sua segurança, pois nunca confiaria em meus usuários o suficiente para manter em segredo os arquivos de configuração.
Robert Baron
Como você implanta aplicativos da Web que lidam com códigos de erro? Ou nomes de campos json? Estou confuso com o que você pensa que estou fazendo, que é um problema de segurança. A execução de código arbitrário na máquina do meu cliente é absolutamente uma questão de segurança, permitindo que eles analisem o json de um servidor não parece ser, a menos que esteja faltando alguma coisa.
Enderland
Trabalhei em empresas, que tinham como base de segurança os geradores de números aleatórios no estilo DOS e os valores de sementes armazenados como constantes. Estes tendiam a ser corrigidos muito rapidamente após serem apontados. No entanto, se você colocar o valor inicial para o mundo, você daria a chave para o reino. Como seu software parece ser principalmente baseado na Web, mantenha a configuração em um objeto JSON e deixe cada um dos idiomas analisar o mesmo arquivo compartilhado.
Robert Baron
Os nomes de campo JSON provavelmente não precisam e não precisam ser constantes. Quais seriam as chances de que esses nomes de campos precisassem ser alterados, mas você não altera o nome da constante em si? Provavelmente você provavelmente se beneficiará da geração de código para acessar entradas ou do uso de linguagem de expressão como ObjectPath.
Lie Ryan