Die meisten Anwendungen, die wir Entwickler schreiben, müssen beim Start extern parametrisiert werden. Wir übergeben Dateipfade, Pipe-Namen, TCP / IP-Adressen usw. Bisher habe ich die Befehlszeile verwendet , um diese an die zu startende Anwendung zu übergeben. Ich musste die Befehlszeile analysieren main
und die Argumente dorthin leiten, wo sie benötigt werden. Dies ist natürlich ein gutes Design , aber für eine große Anzahl von Argumenten schwer zu pflegen . Kürzlich habe ich mich für den Umgebungsvariablenmechanismus entschieden . Sie sind global und von überall zugänglich, was aus architektonischer Sicht weniger elegant ist , aber die Codemenge begrenzt .
Dies sind meine ersten (und möglicherweise recht flachen) Eindrücke zu beiden Strategien, aber ich würde gerne Meinungen erfahrener Entwickler hören. Was sind die Höhen und Tiefen der Verwendung von Umgebungsvariablen und Befehlszeilenargumenten, um Argumente an einen Prozess zu übergeben? Ich möchte folgende Punkte berücksichtigen:
- Designqualität (Flexibilität / Wartbarkeit),
- Speicherbeschränkungen,
- Portabilität der Lösung.
Bemerkungen:
Anzeige. 1. Dies ist der Hauptaspekt, der mich interessiert.
Anzeige. 2. Das ist ein bisschen pragmatisch. Ich kenne einige Einschränkungen unter Windows, die derzeit sehr groß sind (über 32 KB sowohl für die Befehlszeile als auch für den Umgebungsblock). Ich denke, dies ist jedoch kein Problem, da Sie nur eine Datei verwenden sollten, um bei Bedarf Tonnen von Argumenten zu übergeben.
Anzeige. 3. Ich weiß fast nichts über Unix, daher bin ich mir nicht sicher, ob beide Strategien genauso ähnlich sind wie unter Windows. Erläutern Sie dies bitte.
quelle
Antworten:
1) Ich würde empfehlen, Umgebungsvariablen so weit wie möglich zu vermeiden.
Vorteile von Umgebungsvariablen
Nachteile von Umgebungsvariablen
Meine Meinung
They are global and accessible from anywhere, which is less elegant from architectural point of view, but limits the amount of code
erinnert mich an Rechtfertigungen für die Verwendung globaler Variablen;)Meine Narben, weil ich die Schrecken der Überbeanspruchung durch Umgebungsvariablen aus erster Hand erlebt habe
2) Grenzen
Wenn ich die Grenzen dessen verschieben würde, was die Befehlszeile enthalten kann oder was die Umgebung verarbeiten kann, würde ich sofort umgestalten.
Ich habe JSON in der Vergangenheit für eine Befehlszeilenanwendung verwendet, die viele Parameter benötigte. Es war sehr praktisch, Wörterbücher und Listen zusammen mit Zeichenfolgen und Zahlen verwenden zu können. Die Anwendung benötigte nur einige Befehlszeilenargumente, von denen eines der Speicherort der JSON-Datei war.
Vorteile dieses Ansatzes
What won't fit into command line parameters?
) wie Listen darzustellenHinweis : Ich möchte dies vom Ansatz der .config-Datei unterscheiden - dies dient nicht zum Speichern der Benutzerkonfiguration. Vielleicht sollte ich dies den Ansatz der 'Befehlszeilen-Parameterdatei' nennen, weil ich ihn für ein Programm verwende, das viele Werte benötigt, die nicht gut in die Befehlszeile passen.
3) Portabilität der Lösung: Ich weiß nicht viel über die Unterschiede zwischen Mac, PC und Linux in Bezug auf Umgebungsvariablen und Befehlszeilenargumente, aber ich kann Ihnen sagen:
Ja, ich weiß - es war nicht sehr hilfreich. Es tut mir Leid. Der entscheidende Punkt ist jedoch, dass Sie erwarten können, dass eine vernünftige Lösung portabel ist, obwohl Sie dies auf jeden Fall für Ihre Programme überprüfen möchten (z. B. wird bei Befehlszeilenargumenten auf allen Plattformen zwischen Groß- und Kleinschreibung unterschieden - auf allen Plattformen - ich weiß es nicht ).
Ein letzter Punkt:
Wie Tomasz erwähnte, sollte es für die meisten Anwendungen, aus denen die Parameter stammen, keine Rolle spielen.
quelle
Sie sollten Leseparameter mithilfe des Strategiemusters abstrahieren . Erstellen eine Abstraktion benannt
ConfigurationSource
mitreadConfig(key) -> value
Verfahren (oder eine wiederkehrendenConfiguration
Objekt / Struktur) mit folgenden Implementierungen:CommandLineConfigurationSource
EnvironmentVariableConfigurationSource
WindowsFileConfigurationSource
- Laden aus einer Konfigurationsdatei vonC:/Document and settings...
WindowsRegistryConfigurationSource
NetworkConfigrationSource
UnixFileConfigurationSource
- - Laden aus einer Konfigurationsdatei von/home/user/...
DefaultConfigurationSource
- StandardeinstellungenSie können das Muster der Verantwortungskette auch verwenden , um Quellen in verschiedenen Konfigurationen zu verketten, z. B.: Wenn kein Befehlszeilenargument angegeben wird, versuchen Sie es mit der Umgebungsvariablen. Wenn alles andere fehlschlägt, geben Sie die Standardwerte zurück.
Anzeige 1. Mit diesem Ansatz können Sie nicht nur die Lesekonfiguration abstrahieren, sondern auch den zugrunde liegenden Mechanismus problemlos ändern, ohne den Clientcode zu beeinträchtigen. Sie können auch mehrere Quellen gleichzeitig verwenden, zurückgreifen oder Konfigurationen aus verschiedenen Quellen erfassen.
Anzeige 2. Wählen Sie einfach die geeignete Implementierung aus. Natürlich passen einige Konfigurationseinträge beispielsweise nicht in Befehlszeilenargumente.
Anzeige 3. Wenn einige Implementierungen nicht portierbar sind, lassen Sie zwei, eine wird stillschweigend ignoriert / übersprungen, wenn sie für ein bestimmtes System nicht geeignet ist.
quelle
rem
und ein gut lesbares Formular erstellenset
. Wenn Sie einen Prozess erzeugen, haben Sie genau das,setenv
was Sie möchten, bevor Sie beginnenspawnl
. Es ist bequem, lesbar und flexibel. Warum sollten Sie .config anstelle der Umgebung verwenden? Das ist hier die Frage.ACTION
und einen optionalenNOTIFY
. Programm A setzt Ihr ProgrammACTION=if owner=nobody set owner=bob
und führt esNOTIFY=send
dann aus. Ihr Programm aktualisiert ein Element, sieht dann, dassNOTIFY
es festgelegt ist und ausgeführt wirdsend
. Dassend
Programm sendet eine E-Mail an Bob und führt dann Ihr Programm erneut ausACTION=set last_send = today
. Es möchte keine Benachrichtigung, daher wird es nicht festgelegtNOTIFY
. Es wurde jedoch von Programm A geerbtNOTIFY
, sodass Ihr Programm den letzten Lauf auf heute aktualisiert und dann ausgeführt wirdsend
. Endlosschleife.Ich denke, diese Frage wurde bereits ziemlich gut beantwortet, aber ich denke, sie verdient ein Update für 2018. Ich bin der Meinung, dass ein nicht erwähnter Vorteil von Umgebungsvariablen darin besteht, dass sie im Allgemeinen weniger Kesselplattencode erfordern, um damit zu arbeiten. Dies sorgt für saubereren, besser lesbaren Code. Ein großer Nachteil ist jedoch, dass sie eine Isolationsschicht von verschiedenen Anwendungen entfernen, die auf demselben Computer ausgeführt werden. Ich denke, hier strahlt Docker wirklich. Mein bevorzugtes Entwurfsmuster besteht darin, ausschließlich Umgebungsvariablen zu verwenden und die Anwendung in einem Docker-Container auszuführen. Dies beseitigt das Isolationsproblem.
quelle