Подтвердить что ты не робот

Стратегия передачи аргументов - переменные среды по сравнению с командной строкой

Большинство приложений, которые разработчики пишут, должны быть подвергнуты внешнему параметризации при запуске. Мы передаем пути к файлам, имена труб, адреса TCP/IP и т.д. До сих пор я использовал командную строку , чтобы передать их в запущенное приложение. Мне пришлось анализировать командную строку в main и направлять аргументы туда, где они нужны, что, конечно, хороший дизайн, но его трудно поддерживать для большого количества аргументов. Недавно я решил использовать механизм переменных среды. Они глобальны и доступны из любого места, что менее элегантно с архитектурной точки зрения, но ограничивает количество кода.

Это мои первые (и, возможно, довольно мелкие) впечатления от обеих стратегий, но я хотел бы услышать мнения более опытных разработчиков - . Каковы взлеты и падения использования переменных окружения и аргументов командной строки для прохождения аргументы для процесса? Я хотел бы принять во внимание следующие вопросы:

  • качество дизайна (гибкость/ремонтопригодность),
  • ограничения памяти,
  • переносимость решения.

Примечания:

Ad. 1. Это основной аспект, который меня интересует.

Ad. 2. Это немного прагматично. Я знаю некоторые ограничения на Windows, которые в настоящее время огромные (более 32 КБ для командной строки и блока среды). Я думаю, это не проблема, потому что вам нужно использовать файл, чтобы передать тонны аргументов, если вам нужно.

Ad. 3. Я почти ничего не знаю об Unix, поэтому я не уверен, что обе стратегии так же полезны, как и для Windows. Поработайте над этим, если хотите.

4b9b3361

Ответ 1

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) Пределы

Если бы я нажимал пределы того, что может удерживать командная строка, или то, что может обрабатывать среда, я бы немедленно реорганизовал.

Я использовал JSON в прошлом для приложения с командной строкой, которому нужно было много параметров. Было очень удобно использовать словари и списки, а также строки и номера. Приложение заняло всего несколько аргументов командной строки, одним из которых было расположение файла JSON.

Преимущества такого подхода

  • не нужно было писать много (болезненный) код для взаимодействия с библиотекой CLI - может быть больно заставить многие из общих библиотек выполнять сложные ограничения ( "сложным" я имею в виду более сложным, чем проверка определенного ключа или чередование между набором клавиш)
  • не нужно беспокоиться о требованиях к библиотекам CLI для порядка аргументов - просто используйте объект JSON!
  • легко представлять сложные данные (отвечающие What won't fit into command line parameters?), такие как списки
  • легко использовать данные из других приложений - как для создания, так и для анализа программно
  • легкость размещения будущих расширений

Примечание. Я хочу отличить это от подхода .config-file - это не для сохранения конфигурации пользователя. Может быть, я должен назвать это "параметром командной строки", потому что я использую его для программы, для которой требуется множество значений, которые не подходят в командной строке.


3). Переносимость порта: я не знаю много о различиях между Mac, ПК и Linux в отношении переменных окружения и аргументов командной строки, но могу вам сказать:

  • все три имеют поддержку переменных окружения
  • все они поддерживают аргументы командной строки

Да, я знаю - это было не очень полезно. Прости. Но ключевым моментом является то, что вы можете ожидать, что разумное решение будет переносимым, хотя вы определенно хотите проверить это для своих программ (например, являются ли аргументы командной строки аргументами с учетом регистра на любых платформах? платформы? Я не знаю).


Последняя точка:

Как отметил Томаш, это не должно иметь большого значения для большинства приложений, из которых были получены параметры.

Ответ 2

Вы должны абстрагировать параметры чтения с помощью Strategy. Создайте абстракцию с именем ConfigurationSource, имеющую метод readConfig(key) -> value (или возвращающий некоторый объект/структуру Configuration) со следующими реализациями:

  • CommandLineConfigurationSource
  • EnvironmentVariableConfigurationSource
  • WindowsFileConfigurationSource - загрузка из файла конфигурации из C:/Document and settings...
  • WindowsRegistryConfigurationSource
  • NetworkConfigrationSource
  • UnixFileConfigurationSource - - загрузка из файла конфигурации из /home/user/...
  • DefaultConfigurationSource - defaults
  • ...

Вы также можете использовать Цепь ответственности" для объединения источников в различные конфигурации, например: если аргумент командной строки не указан, попробуйте переменную окружения и если все остальное терпит неудачу, верните defauls.

Объявление 1. Этот подход не только позволяет абстрагировать конфигурацию чтения, но вы можете легко изменить базовый механизм без какого-либо влияния на код клиента. Также вы можете использовать сразу несколько источников, отступать или собирать конфигурацию из разных источников.

Объявление 2. Просто выберите, какая версия подходит. Конечно, некоторые записи конфигурации не подходят, например, в аргументы командной строки.

Объявление 3. Если некоторые реализации не переносимы, имейте два, один молча игнорируется/пропускается, если не подходит для данной системы.

Ответ 3

Я думаю, что на этот вопрос уже довольно хорошо ответил, но я чувствую, что он заслуживает обновления 2018 года. Я чувствую, что неизменное преимущество экологических переменных заключается в том, что они обычно требуют меньше котельного табличного кода для работы. Это делает более понятным код. Однако серьезным недостатком является то, что они удаляют слои изоляции из разных приложений, работающих на одной машине. Я думаю, что именно здесь Докер действительно сияет. Мой любимый шаблон дизайна - исключительно использовать переменные среды и запускать приложение внутри контейнера Docker. Это устраняет проблему изоляции.