라이브러리 내에서 STDIN에서 읽는 반 패턴으로 간주됩니까?


39

직장에서 진행중인 대규모 프로젝트를위한 라이브러리를 작성하는 동안 전자 메일 주소로 토큰을 보낸 다음 코드로 다시 전달하여 나중에 사용할 수있는 문제가 발생했습니다.

내 동료는 STDIN (Python : 사용)에서 읽은 code = input("Enter code: ")다음 사용자에게 전달하도록 지시했지만 라이브러리는 서버의 백그라운드 작업에 사용될 수 있으므로 나쁜 습관처럼 보입니다. .

나는 이것이 반 패턴으로 간주되는지 아닌지 궁금했다.


45
나쁜 것은 아니지만 모든 것이 "반 패턴 (anti-pattern)"은 아니지만 이것이 확실히 나쁘다.
Phoshi

4
"패턴"은 프로그래머가 자주하는 일을 의미합니다. (A) 나쁜 생각과 (B) 개발자가 항상하는 일을하는 것이 반 패턴 일뿐입니다.
Solomon Slow

20
반 패턴이 되기에는 너무 멍청하다. 안티 패턴은 자연스럽고 합리적인 것처럼 보이지만 파헤칠 때 나쁜 것으로 판명되었습니다. 여기서 설명하는 것은 분명히 끔찍합니다.
Evan Harper

나는 어떤 대답의 요점도 보지 못했습니다. 사용자 토큰 연습의 요점은 사용자의 전자 메일 주소가 작동 함을 증명해야합니다. 그것이 요점이 아니라면 단순히 토큰을 저장하는 것이 훨씬 간단합니다.
emory

2
이것은 꽤 끔찍합니다. 이와 같은 토큰을 반드시 전달해야하는 경우 라이브러리를 사용하여 별도의 실행 파일을 만들고 토큰을 stdin에 전달할 수 있습니다. 그러나 호출 실행 파일의 stdin을 빼앗기는 것은 아닙니다.
GrandmasterB

답변:


78

일반적인 지침으로 라이브러리는 환경과 완전히 분리되어야합니다. 즉, 표준 스트림, 특정 파일에 대해 작업을 수행하거나 사용 된 환경이나 컨텍스트에 대한 기대가 없어야합니다.

물론이 규칙에는 예외가 있지만 그럴만한 이유가 있어야합니다. 를 사용하는 경우 stdin어떤 이유도 찾을 수 없습니다 (라이브러리가 실제로 std::cinC ++ 과 같은 stdin에서 읽는 루틴을 제공하지 않는 한 ). 또한 I / O 스트림을 하드 코딩하지 않고 매개 변수에서 가져 오면 유연성이 높아져서 수행 할 가치가 없습니다.


36
환경과의 상호 작용이라는 특정 목표를 가진 라이브러리는 예외입니다. 그럼에도 불구하고 환경의 세부 사항은 추상화되어야합니다. 예를 들어 그래픽 드라이버는 PCIe 버스와 통신해야하지만 버스 ID는 구성을 통해 제공되어야합니다.

이것은 내가 생각한 일종의 예외입니다. 제 생각은 일반적으로 텍스트 환경 사용자 인터페이스 라이브러리 인 ncurses 에 더 가깝습니다 . 그 목적이 사용자 입력을 읽고 사용자 출력을 제공하는 것이라면 그럴만한 이유가 있습니다.
SF.

5
@SF. 심지어 같은 라이브러리 의 ncurses는 당신은 표준 입력과 표준 출력을 리디렉션 할 수있는 프로그램을 작성 할 수 있습니다 아니라 0과 1의 사용을 하드 코딩하는 것보다 인수로 파일 기술자의 쌍을해야하고 대신에 당신은 열려 /dev/tty와 통신하기 위해 사용자. 터미널없이 프로그램을 시작하고을 사용하여 자체 터미널을 열 수도 있습니다 xterm -S.
kasperd

3
@kasperd : 가장 좋은 방법은 합리적인 기본값을 제공하고이를 무시하는 기능입니다.
SF.

1
이 특별한 경우에는 스트림 을 입력 으로 요구할 이유가 없습니다 . 왜 토큰 을 매개 변수로 받아들이지 않습니까?
jpmc26

16

필자는 이것이 반 패턴이 아니라 제대로 디자인되지 않은 라이브러리라고 생각합니다. 입력을 직접 전달할 수있는 메소드 매개 변수로 문자열을 요청하는 것은 쉽지 않습니다.

이것이이 사용법에 맞지 않으면 메소드 매개 변수는 스트림 일 수 있으며 STDIN이 메소드에 전달됩니다.

이 사용법에 맞지 않으면 라이브러리가 충분히 유연하지 않습니다.


4

라이브러리에서 어디서나 입력을 읽는 사용자 제공 함수에 콜백을 설정 한 다음 해당 함수를 사용하는 라이브러리의 모든 부분으로 적절한 값을 반환하는 기능을 고려하십시오.


1

stdin에서 읽은 경우 stdin의 프로그램 레벨 소유권을 원한다는 의미입니다. stdin에서 읽는 다른 라이브러리와는 호환되지 않으며 사용 방법에 대한 덜 구체적인 프로토콜입니다. 적어도 내 자신의 개인 용어집에서 이것은 라이브러리를 프레임 워크로 만들 것 입니다.

그러나이 경우 라이브러리는 입력 파일 디스크립터 만 가져야합니다.


0

@ Paul92의 대답은 일반적인 일반적인 토론이지만 가능한 깨끗한 (ish) 솔루션을 제공하고 싶습니다 .

라이브러리 인이 코드는 모든 런타임 환경에 적용 할 수 있어야하므로 STDIN중요한 데이터를 실제로 요청할 수는 없습니다 . 하나의 이유로, 라이브러리 사용자는 여러 가지 이유로 stdin을 사용할 수 없습니다. 대신 어떤 형태의 전략 패턴 을 사용 하여 토큰을 검색하는 방법을 사용자 정의 할 수 있습니다.

파이썬에서 아마도 가장 좋은 옵션은 토큰 가져 오기 전략을 함수 매개 변수로 전달하는 것입니다. 그런 것 :

def stdin_prompt():
    return input("Enter code: ")

def my_library_function(arg1, arg2, ... argn, token_provider = stdin_prompt):
    ...
    token = token_provider()
    ...
    return stuff

# somewhere in the user code
stuff = my_library_function(a1, a2, ... an, lambda: "123456")

이것을 이렇게 생각하십시오. 필요한 토큰은 라이브러리 함수에 대한 인수입니다. 호출 사이트에서 토큰 값을 정적으로 알 수 없으므로 값을 인수로 요청할 수 없습니다. 대신, 호출자는 호출 될 때 토큰을 제공하는 기능을 제공해야합니다.

토큰의 정확한 메커니즘 을 제공 하는 모든 책임 은 이제 라이브러리 기능에서 구체화되었습니다. 함수 소비자는 이제 런타임에 사용 가능한 모든 수단을 통해 토큰을 획득해야합니다. STDIN에게 요청할 수도 있지만 메일 게이트웨이 역할을 할 수도 있고, 메시지가받은 편지함에 팝업 될 때까지 기다렸다가 읽거나 토큰을 추출하여 프로세스를 완전히 자동화 할 수도 있습니다. GUI 대화 상자 또는 웹 기반 양식 일 수 있습니다. 실제로 무엇이든-모든 옵션은 이제 도서관 소비자가 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.