Стратегия передачи аргументов - переменные среды и командная строка - PullRequest
62 голосов
/ 16 сентября 2011

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

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

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

Примечания:

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

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

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

Ответы [ 3 ]

64 голосов
/ 28 сентября 2011

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напоминает мне об оправданиях использования глобальных переменных;)

Мои шрамы от непосредственного переживания ужасов чрезмерного использования переменных среды

  • twoпрограммы, которые нам нужны на работе, которые не могут работать на одном компьютере одновременно из-за столкновений с окружающей средой
  • multiplВерсии программ с одним и тем же именем, но с разными ошибками - поставили целый семинар на колени на несколько часов, потому что местоположение программы было извлечено из среды и было (молча, тонко) неверно.1043 *

    2) Пределы

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

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

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

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

    Примечание : я хочу отличить это от подхода .config-file - этоне для хранения пользовательской конфигурации.Возможно, мне следует назвать это подходом «файл параметров командной строки», потому что я использую его для программы, которой нужно много значений, которые не помещаются в командной строке.


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

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

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


    И последнее замечание:

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

5 голосов
/ 16 сентября 2011

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

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

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

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

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

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

2 голосов
/ 09 мая 2018

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

...