공장 방식 패턴

Factory method pattern

클래스 베이스 프로그래밍에서 팩토리 메서드 패턴은 생성되는 객체의 정확한 클래스를 지정하지 않고 객체의 작성 문제를 처리하기 위해 팩토리 메서드를 사용하는 순환 패턴입니다.이는 컨스트럭터를 호출하는 것이 아니라 팩토리 메서드(인터페이스로 지정되고 자녀 클래스로 구현되거나 기본 클래스로 구현되며 파생 클래스로 선택적으로 덮어쓰기됨)를 호출하여 개체를 만듭니다.

개요

Factory Method 설계 패턴은 반복적인 설계 문제를 해결하고 유연하고 재사용 가능한 객체 지향 소프트웨어, 즉 구현, 변경, 테스트 및 재사용이 용이한 객체를 설계하는 방법을 설명하는 23개의 잘 알려진 설계 패턴 중 하나입니다.

Factory Method 설계 패턴은 다음과 같은 문제를 해결합니다.

  • 서브클래스가 인스턴스화할 클래스를 재정의할 수 있도록 오브젝트를 작성하려면 어떻게 해야 합니까?
  • 클래스가 인스턴스화를 서브클래스로 연기하려면 어떻게 해야 합니까?

공장 출하시 방법 설계 패턴은 이러한 문제를 해결하는 방법을 설명합니다.

  • 오브젝트를 작성하기 위한 별도의 조작(출고시 방식)을 정의합니다.
  • 팩토리 메서드를 호출하여 개체를 만듭니다.

이를 통해 서브클래스의 쓰기를 통해 오브젝트의 작성 방법을 변경할 수 있습니다(인스턴스화할 클래스를 재정의할 수 있습니다).
다음 UML 클래스 다이어그램도 참조하십시오.

정의.

"개체를 만들기 위한 인터페이스를 정의하되, 인스턴스화할 클래스는 하위 클래스가 결정하도록 합니다.Factory 메서드에서는 클래스가 서브클래스에 사용하는 인스턴스화를 연기할 수 있습니다.(Gang Of Four)

오브젝트를 작성하려면 컴포지팅 오브젝트에 포함시키기에는 적절하지 않은 복잡한 프로세스가 필요한 경우가 많습니다.오브젝트의 작성에 의해 코드가 크게 중복되거나 컴포지팅 오브젝트에 액세스 할 수 없는 정보가 필요하거나 충분한 추상화 수준을 제공하지 않거나 컴포지팅 오브젝트의 우려사항이 될 수 있습니다.공장 메서드 설계 패턴은 오브젝트를 작성하는 별도의 메서드를 정의함으로써 이러한 문제를 처리합니다.이러한 메서드는 서브클래스가 덮어쓰고 생성될 제품의 파생 유형을 지정할 수 있습니다.

공장 메서드 패턴은 객체 생성을 공장 메서드를 구현하여 객체를 생성하는 하위 [3]클래스에 위임하기 때문에 상속에 의존합니다.

구조.

UML 클래스 다이어그램

공장 방법 설계 패턴에 대한 샘플 UML 클래스 다이어그램입니다.[4]

위의 UML 클래스 다이어그램에서는Creator를 필요로 하는 클래스Product오브젝트가 인스턴스화되지 않는다.Product1직접 수업합니다.대신,Creator별개라는 뜻하다factoryMethod()제품 오브젝트를 생성하기 위해Creator어떤 콘크리트 클래스가 인스턴스화되는지와 무관합니다.서브클래스Creator인스턴스화할 클래스를 재정의할 수 있습니다.이 예에서는Creator1서브클래스는 추상화를 구현한다.factoryMethod()를 인스턴스화함으로써Product1학급.

미로 게임은 두 가지 모드로 진행됩니다. 하나는 인접한 방과 연결된 일반 방이 있고, 다른 하나는 플레이어를 무작위로 이송할 수 있는 마법 방이 있습니다.

구조.

New WikiFactoryMethod.png

Room는 최종 제품의 기본 클래스입니다(MagicRoom또는OrdinaryRoom).MazeGame이러한 기본 제품을 생산하기 위한 추상 공장 방법을 선언합니다. MagicRoom그리고.OrdinaryRoom는 최종 제품을 구현하는 기본 제품의 하위 클래스입니다. MagicMazeGame그리고.OrdinaryMazeGame의 아류이다MazeGame최종 제품을 생산하는 공장 방법의 구현.따라서, 공장 출하시의 방법에서는, 발신자가 분리됩니다).MazeGame)를 도입하는 것으로 합니다.이것에 의해, 「신규」운용자는 용장화 되어, 오픈/클로즈 원칙을 준수할 수 있게 되어, 변경시에 최종 제품의 유연성이 향상됩니다.

구현 예시

C#

// 실제 객체의 빈 어휘 일반의 인터페이스 아이퍼슨 {     스트링 이름 가져오기(); }  일반의 학급 마을 사람 : 아이퍼슨 {     일반의 스트링 이름 가져오기()     {         돌아가다 '마을 사람';     } }  일반의 학급 시티 퍼슨 : 아이퍼슨 {     일반의 스트링 이름 가져오기()     {         돌아가다 '도시인';     } }  일반의 열거하다 퍼스널 타입 {     시골의,     도시의 }  // </ </filters> /// 공장 구현 - 객체 작성에 사용됩니다. // </filters> 일반의 학급 공장  {     일반의 아이퍼슨 인물 취득(퍼스널 타입 유형)     {         전환하다 (유형)         {             사례. 퍼스널 타입.시골의:                 돌아가다 신규 마을 사람();             사례. 퍼스널 타입.도시의:                 돌아가다 신규 시티 퍼슨();             체납:                 던지다 신규 지원되지 않음예외.();         }     } } 

위의 코드에서는 1개의 인터페이스 생성에 대해 알 수 있습니다.IPerson두 가지 구현이 있습니다.Villager그리고.CityPerson에 전달된 유형에 따라Factory오브젝트, 우리는 원래의 콘크리트 오브젝트를 인터페이스로 반환한다.IPerson.

공장 출하시의 방법은,Factoryclass. 인터페이스를 통해 클래스의 오브젝트를 만들지만 다른 한편으로 서브클래스가 인스턴스화할 클래스를 결정할 수도 있습니다.

일반의 인터페이스 IProduct {     스트링 이름 가져오기();     부울 가격 설정(이중으로 하다 가격.); }  일반의 학급 전화 : IProduct {     사적인 이중으로 하다 _가격;      일반의 스트링 이름 가져오기()     {         돌아가다 "애플 터치패드";     }      일반의 부울 가격 설정(이중으로 하다 가격.)     {         _가격 = 가격.;         돌아가다 진실의;     } }  /* Factory와 거의 마찬가지로 작성한 방법으로 작업을 하기 위한 추가 노출만 가능합니다. 일반의 추상적인 학급 Product Abstract Factory(제품 추출 공장) {     보호되고 있다 추상적인 IProduct 제품 만들기();      일반의 IProduct Get Object(개체 취득)() // 공장 방법의 실장.     {         돌아가다 이것..제품 만들기();     } }  일반의 학급 Phone Concrete Factory : Product Abstract Factory(제품 추출 공장) {     보호되고 있다 덮어쓰다 IProduct 제품 만들기()     {         IProduct 제품. = 신규 전화();         // 개체를 가져온 후 개체로 작업을 수행합니다.         제품..가격 설정(20.30);         돌아가다 제품.;     } } 

보다시피 우리는MakeProduct콘크리트 팩토리에 있습니다.그 때문에, 간단하게 전화할 수 있습니다.MakeProduct()그것을 통해IProduct구체적인 공장 출하시 방법으로 객체를 가져온 후 커스텀 로직을 작성할 수도 있습니다.GetObject는 Factory 인터페이스에서 추상화됩니다.

자바

Java 예는 "Design Patterns"의 예와 유사합니다.

Maze Game은 Rooms를 사용하지만 구체적인 클래스를 만드는 하위 클래스에 Rooms를 만드는 책임을 부여합니다.일반 게임 모드에서는 다음 템플릿 방식을 사용할 수 있습니다.

일반의 추상적인 학급  {     추상적인 무효 연결하다( ); }  일반의 학급 매직룸 확장  {     일반의 무효 연결하다( ) {} }  일반의 학급 통상실 확장  {     일반의 무효 연결하다( ) {} }  일반의 추상적인 학급 메이즈 게임 {      사적인 최종 목록.< >>  = 신규 어레이 리스트<< 고객명 >>님();       일반의 메이즈 게임() {            방1 = make Room();            방2 = make Room();           방1.연결하다(방2);           .더하다(방1);           .더하다(방2);      }       추상적인 보호되고 있다  make Room(); } 

위의 스니펫에서는MazeGame컨스트럭터는 몇 가지 공통 로직을 만드는 템플릿 메서드입니다.이 용어는makeRoom다른 룸을 하위 클래스에서 사용할 수 있도록 룸 생성을 캡슐화하는 팩토리 메서드.마법의 방이 있는 다른 게임 모드를 구현하려면, 이 모드를 오버라이드하는 것으로 충분합니다.makeRoom방법:

일반의 학급 매직메이즈 게임 확장 메이즈 게임 {     @오버라이드     보호되고 있다 매직룸 make Room() {         돌아가다 신규 매직룸();     } }  일반의 학급 노멀 메이즈 게임 확장 메이즈 게임 {     @오버라이드     보호되고 있다 통상실 make Room() {         돌아가다 신규 통상실();     } }  메이즈 게임 통상 게임 = 신규 노멀 메이즈 게임(); 메이즈 게임 매직 게임 = 신규 매직메이즈 게임(); 

PHP

PHP의 다른 예는 다음과 같습니다.이번에는 서브클래싱이 아닌 인터페이스 구현을 사용합니다(단, 서브클래싱을 통해서도 같은 것을 실현할 수 있습니다).공장 출하시의 메서드는 public으로 정의되어 클라이언트코드로 직접 호출할 수도 있습니다(위의 Java 예와 대조됩니다).

/* 공장 및 자동차 인터페이스 */  인터페이스 카팩토리 {     일반의 기능. 메이커(): ; }  인터페이스  {     일반의 기능. get Type(유형)(): 스트링; }  /* 공장 및 자동차의 구체적인 구현 */  학급 Sedan Factory 용구 카팩토리 {     일반의 기능. 메이커():      {         돌아가다 신규 세단();     } }  학급 세단 용구  {     일반의 기능. get Type(유형)(): 스트링     {         돌아가다 '세단';     } }  /* 클라이언트 */  공장 출하시 = 신규 Sedan Factory(); 차비 = 공장 출하시->메이커(); 인쇄물 차비->get Type(유형)(); 

파이썬

Java의 예시와 동일합니다.

부터 abc 수입품 ABC, 추상적 방법   학급 메이즈 게임(ABC):     방어하다 __init__(자신) -> 없음.:         자신. = []         자신._thead_rooms_rooms()      방어하다 _thead_rooms_rooms(자신) -> 없음.:         방1 = 자신.방을 만들다()         방2 = 자신.방을 만들다()          방1.연결하다(방2)         자신..추가하다(방1)         자신..추가하다(방2)      방어하다 놀고(자신) -> 없음.:         인쇄물(f"사용하는 플레이{자신.[0]}")      @http 방법     방어하다 방을 만들다(자신):         올리다 구현되지 않은 오류(「이것을 실장할 필요가 있습니다.)   학급 매직메이즈 게임(메이즈 게임):     방어하다 방을 만들다(자신) -> '매직룸':         돌아가다 매직룸()   학급 노멀 메이즈 게임(메이즈 게임):     방어하다 방을 만들다(자신) -> "일반실":         돌아가다 통상실()   학급 (ABC):     방어하다 __init__(자신) -> 없음.:         자신.접속_실 = []      방어하다 연결하다(자신, : '방') -> 없음.:         자신.접속_실.추가하다()   학급 매직룸():     방어하다 __str__(자신) -> 스트레이트:         돌아가다 '마법의 방'   학급 통상실():     방어하다 __str__(자신) -> 스트레이트:         돌아가다 "일반실"   통상 게임 = 노멀 메이즈 게임() 통상 게임.놀고()  매직 게임 = 매직메이즈 게임() 매직 게임.놀고() 

사용하다

  • ADO.NET에서는 IDbCommand.CreateParameter는 공장 메서드를 사용하여 병렬 클래스 계층을 연결하는 예입니다.
  • QT에서 QMain Window::create Popup Menu는 애플리케이션 코드로 덮어쓸 수 있는 프레임워크로 선언된 공장 메서드입니다.
  • Java에서는 javax.xml.parsers 패키지에 javax.xml.parsers 등 여러 팩토리가 사용됩니다.Document Builder Factory 또는 javax.xml.pars.SAXParser Factory 。
  • HTML5 DOM API에서 Document 인터페이스에는 HTMLlement 인터페이스의 특정 요소를 작성하기 위한 createElement 팩토리 메서드가 포함되어 있습니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 107ff. ISBN 0-201-63361-2.{{cite book}}: CS1 maint: 여러 이름: 작성자 목록(링크)
  2. ^ "The Factory Method design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-17.
  3. ^ Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike (eds.). Head First Design Patterns (paperback). Vol. 1. O'REILLY. p. 162. ISBN 978-0-596-00712-6. Retrieved 2012-09-12.
  4. ^ "The Factory Method design pattern - Structure and Collaboration". w3sDesign.com. Retrieved 2017-08-12.

외부 링크