91

開発者が作成するアプリケーションのほとんどは、起動時に外部からパラメーター化する必要があります。ファイル パス、パイプ名、TCP/IP アドレスなどを渡します。これまでのところ、コマンド ラインを使用してこれらを起動中のアプリケーションに渡してきました。コマンド ラインを解析し、main必要な場所に引数を指定する必要がありました。これはもちろん優れた設計ですが、多数の引数を維持するのは困難です。最近、環境変数メカニズムを使用することにしました。それらはグローバルで、どこからでもアクセスできます。これはアーキテクチャの観点からはあまり洗練されていませんが、コードの量は制限されます

これらは、両方の戦略に対する私の最初の (そしておそらく非常に浅い) 印象ですが、より経験豊富な開発者の意見を聞きたいです。プロセスに引数を渡すために環境変数とコマンドライン引数を使用することの長所と短所は何ですか? 以下の点を考慮したいと思います。

  1. 設計品質(柔軟性・保守性)、
  2. メモリの制約、
  3. ソリューションの移植性。

備考:

広告。1. これが私が興味を持っている主な側面です。

広告。2. これは少し実用的です。現在巨大なWindows のいくつかの制限を知っています(コマンド ラインと環境ブロックの両方で 32kB 以上)。ただし、必要に応じてファイルを使用して大量の引数を渡す必要があるため、これは問題ではないと思います。

広告。3. 私は Unix についてほとんど何も知らないので、両方の戦略が Windows と同様に使用できるかどうかはわかりません。よろしければ、これについて詳しく説明してください。

4

4 に答える 4

85

1) 環境変数をできるだけ避けることをお勧めします。

環境変数の利点

  • どこからでも見えるので使いやすいです。多くの独立したプログラムが情報を必要とする場合、このアプローチは非常に便利です。

環境変数の短所

  • どこからでも見える (削除可能、設定可能) ため、正しく使用するのは困難です。環境変数に依存する新しいプログラムをインストールすると、それらは既存のプログラムを踏みにじるでしょうか? 昨日うっかり遊んでいたときに、うっかり環境変数を台無しにしてしまったのでしょうか?

私の意見

  • プログラムの個々の呼び出しごとに異なる可能性が最も高い引数には、コマンドライン引数を使用します (つまり、n を計算するプログラムには n!)。
  • ユーザーが合理的に変更したいがあまり頻繁ではない引数に構成ファイルを使用します (つまり、ウィンドウがポップアップしたときの表示サイズ)
  • 環境変数は控えめに使用してください -- できれば、変更されないと予想される引数 (つまり、Python インタープリターの場所) に対してのみ使用してください。
  • あなたの指摘They are global and accessible from anywhere, which is less elegant from architectural point of view, but limits the amount of codeは、グローバル変数を使用する正当な理由を思い出させます;)

環境変数の乱用の恐怖を直接体験したことによる私の傷跡

  • 仕事で必要な 2 つのプログラム。環境の衝突により、同じコンピューターで同時に実行することはできません。
  • プログラムの複数のバージョンは、同じ名前でバグが異なります -- プログラムの場所が環境から引き出され、(静かに、微妙に) 間違っていたため、ワークショップ全体が何時間もひざまずきました。

2) 限界

コマンドラインが保持できるもの、または環境が処理できるもののいずれかの限界を押し広げている場合は、すぐにリファクタリングします。

私は過去に、多くのパラメーターを必要とするコマンドライン アプリケーションに JSON を使用しました。文字列や数値だけでなく、辞書やリストも使えるのはとても便利でした。このアプリケーションは、いくつかのコマンド ライン引数しか取りませんでした。そのうちの 1 つは JSON ファイルの場所でした。

このアプローチの利点

  • CLI ライブラリと対話するために多くの (面倒な) コードを書く必要はありませんでした -- 複雑な制約を強制するために多くの共通ライブラリを取得するのは面倒な場合があります (「複雑」とは、特定のキーまたは一連のキー間の代替)
  • 引数の順序に関する CLI ライブラリの要件について心配する必要はありません。JSON オブジェクトを使用するだけです。
  • What won't fit into command line parameters?リストなどの複雑なデータ(回答)を表現しやすい
  • 他のアプリケーションからのデータを簡単に使用できます -- プログラムによる作成と解析の両方
  • 将来の拡張に対応しやすい

: これを .config-file アプローチと区別したい - これはユーザー構成を保存するためのものではありません。コマンドラインにうまく収まらない多くの値を必要とするプログラムに使用するため、これを「コマンドラインパラメーターファイル」アプローチと呼ぶ必要があるかもしれません。


3) ソリューションの移植性: 環境変数とコマンド ライン引数に関する Mac、PC、および Linux の違いについてはよくわかりませんが、次のように言えます。

  • 3つすべてが環境変数をサポートしています
  • それらはすべてコマンドライン引数をサポートしています

はい、わかりました。あまり役に立ちませんでした。ごめんなさい。しかし重要な点は、合理的な解決策が移植可能であると期待できるということです、プログラムでこれを確認したいことは間違いありません (たとえば、コマンド ライン引数はどのプラットフォームでも大文字と小文字を区別しますか? すべてのプラットフォームで? わかりません) )。


最後のポイント:

Tomasz が述べたように、パラメーターがどこから来たかはほとんどのアプリケーションにとって重要ではありません。

于 2011-09-28T19:06:36.637 に答える
8

ストラテジーパターンを使用して読み取りパラメーターを抽象化する必要があります。次の実装を使用して、 ConfigurationSourcehaving readConfig(key) -> valuemethod (または何らかのオブジェクト/構造を返す)という名前の抽象化を作成します。Configuration

  • CommandLineConfigurationSource
  • EnvironmentVariableConfigurationSource
  • WindowsFileConfigurationSource- からの構成ファイルからのロードC:/Document and settings...
  • WindowsRegistryConfigurationSource
  • NetworkConfigrationSource
  • UnixFileConfigurationSource- - からの構成ファイルからのロード/home/user/...
  • DefaultConfigurationSource- デフォルト
  • ...

責任の連鎖パターンを使用して、さまざまな構成でソースを連鎖させることもできます。たとえば、コマンド ライン引数が指定されていない場合は環境変数を試し、他のすべてが失敗した場合はデフォルトを返します。

広告 1. このアプローチでは、読み取り構成を抽象化できるだけでなく、クライアント コードに影響を与えることなく、基になるメカニズムを簡単に変更できます。また、一度に複数のソースを使用して、フォールバックしたり、さまざまなソースから構成を収集したりすることもできます。

広告 2. 適切な実装を選択するだけです。もちろん、一部の構成エントリは、たとえばコマンド ライン引数に適合しません。

広告 3. 一部の実装が移植可能でない場合は、2 つの実装を用意し、1 つは特定のシステムに適していない場合は黙って無視/スキップします。

于 2011-09-16T10:50:50.907 に答える
6

この質問はすでに十分に回答されていると思いますが、2018 年の更新に値すると思います。環境変数の言及されていない利点は、一般に、使用する定型コードが少なくて済むことだと思います。これにより、よりクリーンで読みやすいコードが作成されます。ただし、主な欠点は、同じマシンで実行されているさまざまなアプリケーションからの分離レイヤーが削除されることです。ここが Docker の真価を発揮するところだと思います。私のお気に入りの設計パターンは、環境変数のみを使用し、Docker コンテナー内でアプリケーションを実行することです。これにより、分離の問題が解消されます。

于 2018-05-09T17:22:05.113 に答える