Comment gérer les constantes dans plusieurs langues?

13

J'ai une situation où je soutiens ce qui est fonctionnellement la même bibliothèque dans plusieurs langues. Il y a souvent des constantes qui doivent être partagées entre celles-ci (par exemple, les clés de nom de champ json ou les codes d'erreur).

La façon dont je le fais actuellement est d'avoir du code définissant les constantes dans chaque langue.

Le problème vient de la maintenance. Si j'ajoute un nouveau code d'erreur, je dois le mettre à jour manuellement dans chaque bibliothèque. Bien que cela soit bien pour certains, cela devient fastidieux si je dis 5 sdks à mettre à jour. Ce serait bien d'avoir une seule source de vérité pour eux aussi.

J'ai pensé à une sorte de fichier de configuration, mais il doit ensuite être inclus dans chaque package déployé, ce qui ajoute de la complexité à notre processus de génération / publication.

Existe-t-il un meilleur moyen de gérer la maintenance des constantes partagées entre plusieurs langues?

enderland
la source
Votre approche est bonne, enderland. J'essayais de trouver une meilleure solution pour la redéfinition parce que souvent plusieurs clients consomment des API que je programme et il n'y a vraiment pas de solution élégante. La redéfinition des constantes est toujours la plus simple.
Andy
5
@DavidPacker non non non vous êtes censé avoir une solution vraiment élégante pour moi. Ne me dites pas que c'est le meilleur qui soit! :-)
enderland
1
Je remettais en question mes choix, mais j'ai réalisé que les constantes étaient censées être constantes. Ils sont prévisibles car ils sont constants. En les stockant dans un JSON ou tout autre format généralement analysable, ils ne sont plus vraiment des constantes. Un exemple typique dans mon processus de travail est un objet de notification contenant un typeattribut pour l'identification de la structure lors du transfert à travers le fil. Ayant cela, les clients mobiles définissent uniquement les constantes (types) qu'ils comprennent au moment du moment et ignorent tous les types inconnus. La définition dynamique causerait beaucoup de problèmes.
Andy
Vous avez besoin d'une table de tables qui mappent sur des lignes de constantes de tables de langues.
johnny

Réponses:

10

Bien que je pense que votre approche actuelle est probablement la plus simple et la plus simple, voici quelques idées alternatives:

  • Extrayez vos constantes (et peut-être des modèles) dans un package différent qui est compilé de manière croisée dans toutes vos langues. Vous pourrez peut-être effectuer une compilation croisée de la bibliothèque entière, mais cela peut entraîner de nombreux problèmes. La simple compilation croisée des constantes devrait être suffisamment simple pour qu'il n'y ait pas autant de problèmes. Vous pouvez publier votre package de constantes et en dépendre dans vos bibliothèques spécifiques aux langues. Haxe peut probablement le faire. Cette approche est bonne car vous aurez toujours la vérification à la compilation (pour les langues compilées)
  • Stockez la configuration dans un service central. Par exemple, les services Web soap ont le langage WSDL ( Web Service Description Language ) et les services REST ont le langage WADL ( Web Application Description Language ) qui décrit les opérations et les messages du service. Il existe également des services de configuration centralisée génériques comme Spring Cloud Config
  • Fichier de configuration. Je sais que vous l'avez déjà suggéré, mais je ne pense pas que cela doive beaucoup compliquer votre processus de build / release. Placez votre fichier de configuration dans un projet de construction distinct (où vous pouvez le versionner). Publiez le projet dans vos référentiels de packages spécifiques à toutes les langues (Maven, Nuget, NPM, etc.), puis dans vos bibliothèques spécifiques aux langues, vous pouvez dépendre du package. Cela ne devrait pas être plus complexe que d'avoir un projet supplémentaire dans votre pipeline de build.
  • Comme l'a suggéré RubberDuck, la génération de code est une bonne alternative à la compilation croisée. Vous pouvez générer des définitions constantes pour chaque langue à l'aide d'une configuration commune.
Samuel
la source
5
La génération de code @RubberDuck semble intéressante (en particulier pour l'un de mes cas d'utilisation tangentielle, qui implique déjà un générateur de code de toute façon).
enderland
3

Grande question! J'ai exactement le même problème; mes constantes sont essentiellement: quelles langues sont prises en charge dans mes applications, et des informations supplémentaires sur ces langues en ce qui concerne les fonctionnalités de l'application.

Malheureusement, la meilleure chose que j'ai trouvée (comme vous l'avez) est de simplement redéfinir les constantes pour chaque langue, comme vous le faites actuellement (je sais, vous vouliez certainement entendre cela ).

Évidemment, ça ne va pas parce que c'est l'opposé de SEC ( MOUILLÉ ?? ). Cependant, les constantes devraient changer si rarement que les 5-10 minutes de les redéfinir pour chaque langue ne me dérangent pas vraiment. À la fin de la journée, de petits problèmes avec une solution «élégante» comme la configuration partagée ou la génération de code peuvent prendre des heures ou des jours à résoudre, alors qu'est-ce qui est vraiment gagné? La complexité supplémentaire avec le risque de quelque chose qui ne va pas et qui pourrait prendre des efforts supplémentaires pour réparer n'est pas quelque chose que je veux traiter.

De plus, si votre application a tellement de constantes que les redéfinir par langue lorsque vous les ajoutez ou les changez prend beaucoup de temps, vous pourriez simplement avoir une odeur de code plus importante à gérer et, à ce stade, vous voudrez peut-être activer à quelque chose de plus complexe.

Donc, en bref, les redéfinir pour chaque langue a été ma meilleure solution, et je n'ai pas encore pensé à quelque chose de plus SEC qui n'aurait pas plus de facteur de risque que je veux traiter.

Une chose à vraiment faire, cependant, est de faire en sorte que vos constantes sont bien documentées dans une généralisée (et agnostique de langue) manière (nous avons une prise en pension de documentarion de l' entreprise avec des spécifications, documents divers, « planche à dessin » docs, etc. où nous gardons ce document). Assurez-vous également que des mécanismes sont en place pour synchroniser leurs définitions. C'est à peu près aussi gros problème avec l'approche de duplication que vous aurez, à l'exception d'une petite quantité de détresse psychologique due à la duplication intentionnelle de code. Mais au final, vos changements constants devraient être très délibérés et peu fréquents , donc les problèmes de synchronicité devraient être essentiellement nuls.


Je dois également mentionner qu'au fil des ans, j'ai vu des ports multilingues de diverses bibliothèques (trop fatigués pour se souvenir de ce qu'ils sont en ce moment) écrits par le même groupe qui ont invariablement des constantes définies dans les langues elles-mêmes. Pas de configuration partagée, pas de génération de code (sauf pour les bibliothèques clientes de l'API Google ... mais allez, Google a les ressources pour permettre une telle complexité). Je pense donc que nous avons frappé un mur de briques sur celui-ci. Peut-être que quelqu'un finira par trouver une bibliothèque pour résoudre ce problème;)

Chris Cirefice
la source
0

Espérons que le cœur de votre bibliothèque soit écrit dans une langue et que les autres bibliothèques utilisent FFI ( https://en.wikipedia.org/wiki/Foreign_function_interface ) pour appeler la bibliothèque principale. Cela vous donnerait l'emplacement central pour fournir une API à partir de laquelle publier les constantes et les définitions. De cette façon, tout est autonome dans la bibliothèque. Je ne fais que mentionner cela car cela ne semble pas être inclus dans la réponse de Samuel.

Je pense que cela dépend vraiment de la capacité de votre base d'utilisateurs. Sont-ils suffisamment capables pour gérer le passage d'un autre fichier de configuration? Sont-ils capables de configurer un nouveau service? Pour la grande majorité des utilisateurs que j'ai soutenus, je voudrais que tout soit autonome - de cette façon, les utilisateurs n'auraient pas à y penser.

Robert Baron
la source
1
Hopefully, the core of you library is written in one language, and the other libraries use FFI Malheureusement, nous avons des bibliothèques pour un client Web et un code serveur (en plusieurs langues), donc ... ce ne serait pas trivial à retirer (et probablement une vulnérabilité de sécurité si nous pouvions dans l'application Web pour commencer).
enderland
Je suggère que vous amélioriez votre sécurité, car je ne ferais jamais suffisamment confiance à mes utilisateurs pour garder les fichiers de configuration secrets.
Robert Baron
Comment déployez-vous des applications Web qui gèrent les codes d'erreur? Ou les noms de champs json? Je suis confus par ce que vous pensez que je fais, c'est un problème de sécurité. L'exécution de code arbitraire sur la machine de mon client est absolument un problème de sécurité, leur permettant d'analyser json à partir d'un serveur ne semble pas l'être sauf si je manque quelque chose.
enderland
J'ai travaillé dans des entreprises dont les bases de sécurité étaient des générateurs de nombres aléatoires de style DOS et des valeurs de départ stockées sous forme de constantes. Ceux-ci avaient tendance à être fixés très rapidement après avoir été signalés. Cependant, si vous mettez la valeur de départ dans le monde, vous donneriez la clé du royaume.Comme votre logiciel semble être principalement basé sur le Web, conservez la configuration dans un objet JSON et laissez chacune des langues analyser la même chose. fichier partagé.
Robert Baron
Les noms de champs JSON n'ont probablement pas et ne devraient pas avoir besoin d'être constants. Quelles seraient les chances que ces noms de champ devraient changer, mais vous ne changez pas le nom de la constante elle-même? Vous êtes probablement plus susceptible de bénéficier de la génération de code pour accéder aux entrées ou de l'utilisation d'un langage d'expression comme ObjectPath.
Lie Ryan