La plupart des applications que nous développons doivent être paramétrées en externe au démarrage. Nous transmettons les chemins de fichiers, les noms de canaux, les adresses TCP/IP, etc. Jusqu'à présent, j'ai utilisé la ligne de commande pour les transmettre à l'application en cours de lancement. J'ai dû analyser la ligne de commande dans main
et diriger les arguments là où ils sont nécessaires, ce qui est bien sûr un bon design, mais est difficile à maintenir pour un grand nombre d'arguments. Récemment, j'ai décidé d'utiliser le mécanisme des variables d'environnement . Ils sont globaux et accessibles de partout, ce qui est moins élégant du point de vue architectural, mais limite la quantité de code.
Ce sont mes premières impressions (et peut-être assez superficielles) sur les deux stratégies, mais j'aimerais entendre les opinions de développeurs plus expérimentés - Quels sont les hauts et les bas de l'utilisation des variables d'environnement et de la ligne de commande des arguments pour passer des arguments à un processus? Je voudrais prendre en compte les points suivants:
Remarques:
Un d. 1. C'est l'aspect principal qui m'intéresse.
Un d. 2. C'est un peu pragmatique. Je connais certaines limitations sur Windows qui sont actuellement énorme (plus de 32 Ko pour la ligne de commande et le bloc d'environnement). Je suppose que ce n'est pas un problème, car vous devez simplement utiliser un fichier pour passer des tonnes d'arguments si vous en avez besoin.
Un d. 3. Je ne connais presque rien d'Unix, donc je ne sais pas si les deux stratégies sont aussi utilisables que sous Windows. Développez cela si vous le souhaitez.
1) Je recommanderais d'éviter autant que possible les variables environnementales.
Avantages des variables environnementales
Inconvénients des variables environnementales
Mon avis
They are global and accessible from anywhere, which is less elegant from architectural point of view, but limits the amount of code
me rappelle les justifications de l'utilisation des variables globales;)Mes cicatrices après avoir vécu les horreurs de la surutilisation des variables environnementales
2) Limites
Si je repoussais les limites de ce que la ligne de commande peut contenir ou de ce que l'environnement peut gérer, je refactoriserais immédiatement.
J'ai utilisé JSON dans le passé pour une application en ligne de commande qui nécessitait beaucoup de paramètres. C'était très pratique de pouvoir utiliser des dictionnaires et des listes, ainsi que des chaînes et des nombres. L'application n'a pris que quelques arguments de ligne de commande, dont l'un était l'emplacement du fichier JSON.
Avantages de cette approche
What won't fit into command line parameters?
) comme les listesNote: Je veux distinguer cela de l'approche du fichier .config - ce n'est pas pour stocker la configuration utilisateur. Je devrais peut-être appeler cela l'approche du "fichier de paramètres de ligne de commande", car je l'utilise pour un programme qui a besoin de beaucoup de valeurs qui ne correspondent pas bien à la ligne de commande.
3) Portabilité de la solution: je ne connais pas grand-chose aux différences entre Mac, PC et Linux en ce qui concerne les variables d'environnement et les arguments de ligne de commande, mais je peux vous dire:
Oui, je sais - ce n'était pas très utile. Je suis désolé. Mais le point clé est que vous pouvez attendez-vous à ce qu'une solution raisonnable soit portable, bien que vous souhaitiez certainement le vérifier pour vos programmes (par exemple, les arguments de ligne de commande sont-ils sensibles à la casse sur toutes les plates-formes? Sur tous je ne sais pas).
Un dernier point:
Comme Tomasz l'a mentionné, peu importe la plupart des applications d'où proviennent les paramètres.
Vous devez résumer les paramètres de lecture en utilisant le modèle Strategy . Créez une abstraction nommée ConfigurationSource
ayant la méthode readConfig(key) -> value
(ou renvoyant un objet/une structure Configuration
) avec les implémentations suivantes:
CommandLineConfigurationSource
EnvironmentVariableConfigurationSource
WindowsFileConfigurationSource
- chargement depuis un fichier de configuration depuis C:/Document and settings...
WindowsRegistryConfigurationSource
NetworkConfigrationSource
UnixFileConfigurationSource
- - chargement depuis un fichier de configuration depuis /home/user/...
DefaultConfigurationSource
- valeurs par défautVous pouvez également utiliser Chaîne de responsabilité modèle pour chaîner les sources dans diverses configurations comme: si l'argument de ligne de commande n'est pas fourni, essayez la variable d'environnement et si tout le reste échoue, retournez les valeurs par défaut.
Annonce 1. Cette approche vous permet non seulement d'abstraire la configuration de lecture, mais vous pouvez facilement changer le mécanisme sous-jacent sans aucun effet sur le code client. Vous pouvez également utiliser plusieurs sources à la fois, en reculant ou en rassemblant la configuration à partir de différentes sources.
Annonce 2. Choisissez simplement la mise en œuvre appropriée. Bien sûr, certaines entrées de configuration ne rentrent pas par exemple dans les arguments de ligne de commande.
Annonce 3. Si certaines implémentations ne sont pas portables, en avoir deux, une ignorée/ignorée silencieusement lorsqu'elle ne convient pas à un système donné.
Je pense que cette question a déjà été assez bien répondu, mais j'ai l'impression qu'elle mérite une mise à jour 2018. Je pense qu'un avantage non mentionné des variables environnementales est qu'elles nécessitent généralement moins de code de plaque de chaudière pour fonctionner. Cela rend le code plus lisible et plus propre. Cependant, un inconvénient majeur est qu'ils suppriment des couches d'isolement des différentes applications s'exécutant sur la même machine. Je pense que c'est là que Docker brille vraiment. Mon modèle de conception préféré consiste à utiliser exclusivement des variables d'environnement et à exécuter l'application à l'intérieur d'un conteneur Docker. Cela supprime le problème d'isolement.