글로벌 요청 컨텍스트-안티 패턴?


12

저는 오늘 파이썬 웹 프레임 워크와 그에 대한 인상에 대해 제 동료에게 이야기하고있었습니다. 전 세계 요청을받은 Flask가 악취가 나고 반 패턴이라고 생각합니다.

문서는 요청 컨텍스트에 대해 말 :

반대로 요청을 처리하는 동안 몇 가지 다른 규칙이 있습니다.

  • 요청이 활성화되어있는 동안 컨텍스트 로컬 객체 (flask.request 및 기타)는 현재 요청을 가리 킵니다.
  • 모든 코드는 언제든지 이러한 객체를 보유 할 수 있습니다.

이 디자인 결정의 기본 개념을 이해하고 응용 프로그램을 더 단순하게 만드는 것 같습니다. Thread Locals 의 경우와 마찬가지로 타협입니다 .

일반적으로 스레드 로컬을 사용하는 것은 그리 좋은 생각이 아닙니다. 스레드 개념을 기반으로하지 않는 서버에서는 문제가 발생하여 큰 응용 프로그램을 유지 관리하기가 어렵습니다. 그러나 Flask는 대규모 응용 프로그램이나 비동기 서버용으로 설계된 것이 아닙니다. 플라스크는 전통적인 웹 애플리케이션을 빠르고 쉽게 작성할 수 있기를 원합니다.

현재 요청 정보로 글로벌 오브젝트를 패치하는 것이 안티 패턴입니까?

정적 코드 분석기의 관점에서 볼 때 전역 상태이기 때문에 그렇지 않다고 생각합니다. 그리고 프로그래머로서 나는 문서를 주의 깊게 읽지 않으면 어떻게 작동하는지 이해할 수 없습니다 . 그리고 이것은 테스트에 영향을 미칩니다 .

요청을 뷰에 대한 인수로 전달하는 것이 좋지 않습니까? 더 읽기 쉽고 명확하며 디버깅하기 쉽다고 생각합니다. 그리고 글로벌 상태를 피하십시오.


2
이러한 반 패턴의 특정 부정적인 영향이 무엇인지 실제로 언급하지 않았습니다. 나는 사실적인 근거가없는 포괄적 인 일반을 불신한다.
Robert Harvey

2
좋은 질문이지만 슬프게도 많은 답변이 없습니다
sleepycal

답변:


4

많은 웹 프레임 워크가 동일한 구조, 즉 전역 요청을 갖습니다. 어떤 의미에서는 실제로 한 번에 하나의 요청 만 있기 때문에 수행하는 것이 옳습니다.

그렇다면 매개 변수로 요청을 전달할 때 어떤 점이 있습니까? 아니요. 요청은 요청이며 매개 변수는 다른 시간에 다른 항목을 전달하기위한 것입니다.

실제 더 큰 응용 프로그램의 낮은 수준을 고려하기 시작하면 문제가 온다. 전역 요청의 경우 전역으로 요청에 액세스하는 모든 곳에서 코드를 작성하려는 유혹이 있습니다. 그것은 매우 나쁜 것 입니다. 코드의 다른 부분 사이에 커플 링을 생성하여 변경하기가 어렵고 테스트하기가 어렵습니다.

그래서 제 대답은 : 전 세계 요청을 유지하고 함께 살아라. 그러나 개별 모듈 또는 기능에 전체 요청이 필요하지 않은 경우 필요한 데이터 만 매개 변수로 전달하십시오. 참조 자, URL 또는 명령 꼬리 및 필요한 비트 만 함수에 전달하십시오. 이를 통해 코드를 모듈 식으로 유지하고 커플 링을 줄이며 테스트 가능성을 향상시킬 수 있습니다.

작은 프로그램의 경우 거의 중요하지 않지만 더 큰 프로그램의 경우 실제 생명을 구할 수 있습니다.


3

(나는 약간의 공감대를 얻을 수는 있지만 대담하게 대답 할 것입니다.)

플라스크는 마이크로 프레임 워크입니다. 프릴을 포기하면서 단순함의 이점을 누릴 수 있습니다. 직감 수준에 동의하는 동안 한 가게에서 flask + gunicorn을 사용하여 필요한 멀티 스레딩을 제공한다는 것을 알고 있습니다. 정말 잘 작동했습니다 . 스크립트의 각 인스턴스는 하나의 요청 (예 : 하나의 스레드)을 처리했으며 gunicorn은 여러 스레드 중 "팬 아웃"을 처리했습니다. 그것은 훌륭했다.

따라서 여러 스레드가 전역 상태를 위해 경쟁 할 수 있다고 생각하는 인식 단점은 스레드 당 하나의 스크립트이기 때문에 문제가되지 않습니다.

(여기서 문제가 생길 수있는 곳) 파이썬 세계에서는 스레딩과 동시성이 다르기 때문에 자바 프레임을 사용하면 짜내기가 어렵습니다. Java로 부여되거나 응용 프로그램 컨테이너가 투명하게 처리하는 것은 Python의 표면에 훨씬 가깝습니다.

하나의 스레드가 내 스크립트의 한 번의 호출을 처리한다는 것이 이상했지만, 동시에 상자에서 수십 개의 실행을 한 후에 더 나은 느낌을 받았습니다.


4
스레드 안전 등에 대해서는 걱정하지 않습니다. 이 경우 Flask가 잘 작동한다고 생각합니다. 내 질문은 응용 프로그램 설계 및 아키텍처에 관한 것입니다. 요청을 뷰에 대한 인수로 전달하는 것이 좋지 않습니까? 더 읽기 쉽고 명확하며 디버깅하기 쉽다고 생각합니다.
warvariuc

2

파이썬에서는 print표준 출력으로 인쇄 하는 명령 (v3 이후 기능)이 있습니다. STDOUT으로 인쇄하도록 명시 적으로 지정하지 않습니다. 암시 적으로 뒤에서 이루어집니다.

암시 적으로. 파이썬에서. 그리고 아무도 그것에 대해 문제가 없습니다. 왜?

print파이썬 언어의 일부이며, 파이썬 프로그래밍의 한 가지 요구 사항은 ... 파이썬을 아는 것입니다. 그리고 파이썬을 알고 있다면 printSTDOUT 을 목표로 한다는 것을 알고 있습니다. 놀랍지 않습니다.

파이썬은 언어로서 자신의 관습을 정의하고 프로그래머가 알고 있다고 가정 할 수 있습니다.

프레임 워크는 또한 그 특권을 누리고 있습니다. 이는 프레임 워크와 라이브러리의 주요 차이점 중 하나입니다. 라이브러리를 사용하기 위해 라이브러리를 배울 필요는 없습니다. 필요한 API의 일부만 찾으면 언어 (또는 프레임 워크)의 규칙을 따른다고 가정하면됩니다. 그렇기 때문에 GSON 또는 Apache Commons에 대한 지식이있는 직원을 찾는 채용 담당자가 보이지 않습니다. 그러나 JQuery 나 Ruby on Rails 또는 ASP.NET MVC에 대한 경험이있는 직원을 찾는 채용 담당자는 이러한 규칙을 배우고 알고 있어야하는 자체 규칙을 정의하는 프레임 워크이기 때문에이를 알 수 있습니다.

프레임 워크 인 Flask는 스레드 로컬 전역에 컨텍스트를 저장하기위한 규칙을 정의 할 수 있으며 다른 사람을 놀라게하지 않아야하므로 반 패턴이 아닙니다.


2
"stdout"은로 지정된 파일 디스크립터를 의미합니다 sys.stdout. 변경하면 다른 곳으로 인쇄됩니다.
Phoshi

1
또한 >>연산자를 사용 하거나 Python3 file에서 print함수에 인수를 전달 하여 출력 스트림을 무시할 수 있습니다 . 따라서 sys.stdout무시할 수있는 기본값 일뿐입니다.
warvariuc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.