2016-11-29 11 views
2

오픈 스택 중성자에서 아래 코드를 읽었습니다.왜 파이썬에서 팩토리 메소드를 사용합니까?

class APIRouter(wsgi.Router): 

    @classmethod 
    def factory(cls, global_config, **local_config): 
     return cls(**local_config) 

    def __init__(self, **local_config): 
     # do something. Not using local_config 

여기에는 두 가지 질문이 있습니다.

  1. 공장 코드에서 APIRouter 인스턴스를 만드는 데 사용된다는 것을 알 수 있습니다. 그러나 왜 우리는 그것을 필요로합니까? 인스턴스를 가져 오는 데 단지 api_router = ApiRouter()을 사용하지 않는 이유는 무엇입니까?

  2. __init__ 및 공장 local_configglobal_config은 사용되지 않습니다. 왜 우리는 그것을 기능으로 정의 하는가?

나는 생성자 대신에 공장을 사용하기위한 몇 가지 이점이 있어야 같아요. JAVA의 디자인 패턴과 같습니다. 대답이 장점이나 이유를 설명 할 수 있기를 바랍니다. 일부 exapmle로 더 나은

답변

3

이것은 날카로운 질문입니다. 나는 (잘하면 정보에 근거한) 추측을 취할 것입니다. 문제의 OpenStack 코드를 검토하는 동안 내 코드가 아니며이 특정 구성 아키텍처를 사용하지 않기 때문에 추측을 말합니다.

APIRouter()은 주 인스턴스 생성자로 소스 코드에 나타납니다. APIRouter.factory은 주로 정적 구성 파일과 함께 미들웨어 서비스/처리 파이프 라인을 지정하기위한 디자인 인 paste-deploy과 관련되어 나타납니다.

업계에서는 구성 가능한 모듈 (즉, 플러그인 아키텍처가 크게 작성 됨)의 처리 프레임 워크가 시장 성공 가능성이 높은 네트워크 서비스를 구축하기 위해 안정적이고 효과적인 방법이 될 것이라고 상상하는 풍부한 역사를 가지고 있습니다. 그 꿈은 적어도 1980 년대 초 유닉스 시스템 브이의 STREAMS 에까지 미치게된다. 플러그인 아키텍처는 수시로 - 때로는 능숙하게 작동합니다. 그러나 이러한 이유로 어떤 프레임 워크가 성공을 거둔 경우 제품이나 공급 업체와는 별개로 이미 다른 이유로 인해 성공을 거두었습니다. 그래서 워드 프레스, nginx, 아파치 또는 PostgreSQL을위한 플러그인 시스템? 자본! 4 가지 모두에 걸쳐 조정할 수있는 플러그인 시스템과 수십 개의 다른 다양한 엔진이 있습니까? 아마 "너무 멀리 다리." 그러나 나의 냉소주의는 무시한다.

상속 계층 구조와 독립적으로 사용할 객체 유형을 결정할 때마다 팩토리 함수 (또는 여기, 팩토리 메소드)가 의미가 있습니다. 예를 들어, API 라우터의 두 가지 구현을 생각해보십시오. FastAPIRouter은 실제로 빠르지 만 REST 만 지원합니다. StandardAPIRouter은 느리지 만 REST 또는 SOAP 요청을 지원합니다. FastAPIRouter() (FastAPIRouter.__init__())으로 전화 할 경우 에만 FastAPIRouter 인스턴스를 얻을 수 있습니다. 그러나 FastAPIRouter.factory(...)에 SOAP 기능의 필요성을 나타내는 매개 변수가있는 경우 해당 팩토리 메서드는 을 선택하여 StandardAPIRouter 인스턴스를 대신 반품 할 수 있습니다. 당신은 당신이 요구 한 정확한 것을 얻지 못했을 것입니다.하지만 당신이 필요로하는 것을 되돌려줍니다. 그것은 종종 훨씬 더 가치가 있습니다. 팩토리는 생성자이지만, 생성 할 서브 클래스를 선택할 수있는 팩토리입니다. 표준 생성자는 선택할 수 없습니다.

당신은 서로의 인스턴스를 구성하는 클래스를 형제 고유의 꽉 coupling, 당신은 다시 (아마도 우수한 기반으로 손 서브 클래스는 "명령 결정을"만들 것 APIRouter.factory(...)에 대한 일반적인 요구를 상상할 수있는 마음에 들지 않으면) 주어진 매개 변수를 처리하기위한 최상의 구현에 대한 이해. 아직 커플 링이 있습니다 ...하지만 지능과 가치를 제공합니다.

마치 레스토랑에 앉아서 잘못된 서버에 뭔가를 묻는 것과 같습니다. 한 가지 가능한 응답은 "아니오!이게 내 표가 아닙니다."입니다. 고객이 그 점을 높이 평가하지는 않습니다. 더 좋은 대답은 "제이크가 당신의 서버입니다. 나는 그를 데려 올 것입니다." 이것이 공장에서 할 수있는 방법입니다. 그것들은 클래스를위한 특별한 메소드의 일부가 아니다; 특정의 딱딱한 생성자 함수가 없기 때문에 처음에 요청한 객체 대신 적절한 객체로 대체 할 수도 있습니다.

때때로 공장을 파이썬으로 보게됩니다. collections.namedtuple은 다소 위풍 당당한 예입니다. 기존의 고정 된 목록에서 클래스를 선택하는 것만은 아닙니다. 그것은 실제로 귀하의 사양에 따라 전체 천으로 새로운 클래스를 만듭니다. 그러나 Python, Ruby, Perl 및 JavaScript와 같은 동적 언어는 Java와 같이 정적으로 유형이 지정된 언어처럼 자주 공장을 필요로하지 않습니다. 이들의 생성자에는 Java의 동일한 제약 조건이 있지만 언어에는 동적 타이핑 ("후기 바인딩"), 오리 입력 및 상속과 같은 위임을 사용하려는 개발자의 의지가 있습니다. 이 기능 군은 "일의 올바른 대상"을 선택할 수있는 자유를 부여합니다. 기술적 인 필요성과 문화적 선택에 따라 Java 개발자는 유연성을 위해 factory pattern에 훨씬 더 많이 의존합니다.

히스토리 고려 : 오늘날의 많은 미들웨어 개발자들은 엄청난 양의 생태계에서 기술적으로나 경제적으로 모두 Java로 상당한 시간을 보냈습니다. 테스트, 종속성 주입 및 하위 시스템 구성과 같은 "소프트웨어 엔지니어링"영역에 대한 Java의 패턴과 관행은 다른 언어 커뮤니티에도 널리 퍼졌습니다. 패턴, 기대치, 용어는 잘 정립 된 후에도 지속됩니다.

중성자에서 .factory() 생성자를 사용하는 것은 기술적으로나 다른 방법으로는 의미가 있습니다.

하지만 "실제로 ...."몇 가지가 있습니다.

  1. 세계의 중성자 코드를 모두 보았다고 주장 할 수는 없지만 본 코드는 실제로 공장을 사용하지 않습니다. APIRouter.factoryAPIRouter.__init__보다 매력적이며 약간 변경된 호출 순서가 있습니다. 개발자의 감성과 표준화되고 설계된 호출 시그니처와의 정렬은 그 자체로 가치가 있습니다. 그러나 중성자가 표준 생성자의 호출 서명을 똑같이 지정할 수 있기 때문에 이는 좁은 전문성입니다. 현재 공장은 실제로 매개 변수를 사용하거나 지능을 추가하지 않습니다. 그들은 프로 형식 팩토리이고, 사실상 대체 생성자입니다.

  2. 전체 paste-deploy 접근 방식은 구성 파일에서 원하는 구성 요소를 지정하는 것입니다. 이는 원하는 클래스를 명시 적으로 선택하도록 유도하여 유연한 "우리는 어떤 종류의 객체를 구성해야합니까?"라는 필요성과 가치를 제한합니다. 코드의 선택. 동적 언어의 자유도가 공장에서 약간의 빛을 발하는 것처럼 설정 파일은 미들웨어 구성 역할에서 공장의 가치를 감소시킵니다.

두 번째 질문에 대해서는 구성 설정을 사용하지 않는 이유는 무엇입니까? 아마도 APIRouter에는 필요하지 않기 때문일 수 있습니다. 다른 모듈 (예 : 버전 관리 및 IPAM 플러 거블 필터 처리)은 로컬 또는 전역 구성 객체 중 하나를 사용하는 것으로 보입니다 (통과하는 경우 임에도 불구하고). 사용하지 않는 구성 옵션은 공장 접근 방식과 비슷합니다. 구성 시스템의 구조적 특징은 실제로 많이 사용되지는 않지만 APIRouter에서는 불필요합니다.

요약

팩토리 유연 오브젝트 생성을 허용한다. 보다 엄격하게 유형화되고 상속에 초점을 맞춘 언어 일수록 더 많은 공장 패턴이 필요합니다. 플러그인 프레임 워크 또는 확장 가능 서버의 기능으로 매우 유용합니다. 그러나이 특별한 경우에 공장은 매우 가볍게 사용되고 지나치게 사용됩니다.

현재 코드에서 팩토리가 많이 사용되지 않더라도 외부 모듈이나 이후 버전이 더 광범위하게 사용할 수 있기 때문에 팩터를 이해할 수 있다고 주장 할 수 있습니다. 모든 아키텍처 요소가 초기에 프레임 워크의 일부로서 가치를 가지기 위해 사용되어야하는 것은 아닙니다.

+0

답변 해 주셔서 감사합니다. 그러나 나는 constructor 대신에 factory를 사용하는 것이 유리하다고 생각한다. 그 대답이 그 이점을 설명 할 수 있기를 바랍니다. 몇 가지 예를 들어 보겠습니다. –

+0

@KramerLi 나는 기본적으로 사용되지 않았기 때문에 공장의 가치를 주어진 것으로 가정하고 이것들에 대해 비웃었다. 반성 할 때, 나는 그들의 현재 (제한된) 가치/역할뿐만 아니라 가능한 가치/역할을 설명 했어야했다. 답변은 적절하게 다시 작성됩니다. –