인수 전달 전략-환경 변수 대 명령 줄
개발자가 작성하는 대부분의 애플리케이션은 시작시 외부 적으로 매개 변수화되어야합니다. 파일 경로, 파이프 이름, TCP / IP 주소 등 을 전달 합니다. 지금까지 명령 줄 을 사용하여 실행중인 응용 프로그램 에 전달했습니다. 명령 줄을 구문 분석 main
하고 필요한 위치로 인수를 전달해야했습니다. 물론 좋은 디자인 이지만 많은 인수에 대해 유지 관리 하기 가 어렵습니다 . 최근에 환경 변수 메커니즘 을 사용하기로 결정했습니다 . 그것들은 전 세계적이며 어디서나 액세스 할 수 있으며 아키텍처 관점에서는 덜 우아 하지만 코드의 양을 제한합니다 .
이것은 두 전략에 대한 나의 첫 (그리고 아마도 상당히 얕은) 인상이지만, 더 경험이 많은 개발자의 의견을 듣고 싶습니다 . 프로세스에 인수를 전달하기 위해 환경 변수와 명령 줄 인수를 사용하는 경우의 기복은 무엇입니까? 다음 사항을 고려하고 싶습니다.
- 설계 품질 (유연성 / 유지 보수성),
- 메모리 제약,
- 솔루션 이동성.
비고 :
기원 후. 1. 이것이 제가 관심있는 주요 측면입니다.
기원 후. 2. 이것은 약간 실용적입니다. 나는 현재 윈도우에 일부 제한을 알고 거대한 (명령 행 및 환경 블록 모두 32KB 이상). 필요한 경우 파일을 사용하여 수많은 인수를 전달해야하기 때문에 이것이 문제가되지 않는다고 생각합니다.
기원 후. 3. 저는 유닉스에 대해 거의 알지 못하기 때문에 두 전략이 Windows에서와 비슷하게 사용 가능한지 확실하지 않습니다. 원하는 경우 이에 대해 자세히 설명하십시오.
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, PC 및 Linux의 차이점에 대해 많이 알지 못하지만 다음과 같이 말할 수 있습니다.
- 세 가지 모두 환경 변수를 지원합니다.
- 모두 명령 줄 인수를 지원합니다.
Yes, I know -- it wasn't very helpful. I'm sorry. But the key point is that you can expect a reasonable solution to be portable, although you would definitely want to verify this for your programs (for example, are command line args case sensitive on any platforms? on all platforms? I don't know).
One last point:
As Tomasz mentioned, it shouldn't matter to most of the application where the parameters came from.
You should abstract reading parameters using Strategy pattern. Create an abstraction named ConfigurationSource
having readConfig(key) -> value
method (or returning some Configuration
object/structure) with following implementations:
CommandLineConfigurationSource
EnvironmentVariableConfigurationSource
WindowsFileConfigurationSource
- loading from a configuration file fromC:/Document and settings...
WindowsRegistryConfigurationSource
NetworkConfigrationSource
UnixFileConfigurationSource
- - loading from a configuration file from/home/user/...
DefaultConfigurationSource
- defaults- ...
You can also use Chain of responsibility pattern to chain sources in various configurations like: if command line argument is not supplied, try environment variable and if everything else fails, return defauls.
Ad 1. This approach not only allows you to abstract reading configuration, but you can easily change the underlying mechanism without any affect on client code. Also you can use several sources at once, falling back or gathering configuration from different sources.
Ad 2. Just choose whichever implementation is suitable. Of course some configuration entries won't fit for instance into command line arguments.
Ad 3. If some implementations aren't portable, have two, one silently ignored/skipped when not suitable for a given system.
I think this question has been answered rather well already, but I feel like it deserves a 2018 update. I feel like an unmentioned benefit of environmental variables is that they generally require less boiler plate code to work with. This makes for cleaner more readable code. However a major disadvatnage is that they remove a layers of isolation from different applications running on the same machine. I think this is where Docker really shines. My favorite design pattern is to exclusively use environment variables and run the application inside of a Docker container. This removes the isolation issue.
'developer tip' 카테고리의 다른 글
화면이 꺼져있을 때 Android 가속도계가 작동하지 않음 (0) | 2020.11.12 |
---|---|
Subversion 작업 복사본에서 디렉토리 이름을 바꾸는 건전한 방법 (0) | 2020.11.12 |
복사하지 않고 Numpy 배열 연결 (0) | 2020.11.12 |
VisualVM-스레드 상태 (0) | 2020.11.12 |
코드 분석 창이 어디로 갔습니까? (0) | 2020.11.12 |