추상 공장 패턴

Abstract factory pattern
UML 클래스 다이어그램

추상 공장 패턴은 구체적인 클래스를 지정하지 [1]않고 공통 테마를 가진 개별 공장 그룹을 캡슐화할 수 있는 방법을 제공합니다.통상의 사용법에서는, 클라이언트 소프트웨어는 추상 팩토리의 구체적인 실장을 작성한 후, 팩토리의 범용 인터페이스를 사용해 테마의 일부인 구체적인 오브젝트를 작성합니다.클라이언트는 제품[1]범용 인터페이스만 사용하기 때문에 이러한 각 내부 공장에서 어떤 구체적인 개체를 얻는지 알 수 없습니다(또는 신경 쓰지 않습니다).패턴은 객체 생성은 공장 인터페이스에서 공개되는 [2]메서드로 구현되기 때문에 객체 세트의 구현 세부사항을 일반적인 사용에서 분리하고 객체 구성에 의존합니다.

그 예로는 추상적인 팩토리 클래스가 있습니다.DocumentCreator다수의 제품을 작성하기 위한 인터페이스를 제공합니다(예:createLetter()그리고.createResume()). 이 시스템에는 다수의 파생 콘크리트 버전이 있습니다.DocumentCreator같은 계급FancyDocumentCreator또는ModernDocumentCreator, 각각 다른 실장을 가지고 있습니다.createLetter()그리고.createResume()대응하는 오브젝트를 만들 수 있습니다.FancyLetter또는ModernResume이 제품들은 각각 다음과 같은 단순한 추상 클래스에서 파생되었습니다.Letter또는Resume고객이 인지하고 있는 것입니다.클라이언트 코드에 의해 적절한 인스턴스가 취득됩니다.DocumentCreator공장 방법이라고 부릅니다.결과 개체는 각각 동일한 개체에서 생성됩니다.DocumentCreator공통의 테마를 공유한다(모두 화려하거나 현대적인 물건일 것이다).클라이언트는 추상화를 처리하는 방법만 알면 됩니다.Letter또는Resume콘크리트 공장에서 가져온 특정 버전이 아니라 클래스입니다.

팩토리는 객체가 구성되는 코드에서 콘크리트 클래스의 위치입니다.이 패턴을 사용하는 목적은 오브젝트의 생성을 그 사용으로부터 격리하고 구체적인 [2]클래스에 의존하지 않고 관련 오브젝트의 패밀리를 만드는 것입니다.이를 통해 기본 클래스를 사용하는 코드를 변경하지 않고 새로운 파생 유형을 도입할 수 있습니다.

이 패턴을 사용하면 실행 에도 구체적인 구현을 사용하는 코드를 변경하지 않고 상호 교환할 수 있습니다.단, 유사한 설계 패턴과 마찬가지로 이 패턴을 사용하면 코드 초기 작성 시 불필요한 복잡성과 추가 작업이 발생할 수 있습니다.또한 분리 및 추상화 수준이 높을수록 시스템의 디버깅 및 유지보수가 더 어려워질 수 있습니다.

개요

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

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

  • 응용 프로그램이 개체 생성 방법과 어떻게 독립적일 수 있습니까?
  • 클래스가 필요한 오브젝트 작성 방법과 어떻게 독립적일 수 있을까요?
  • 관련 객체 또는 종속 객체의 패밀리를 작성하려면 어떻게 해야 합니까?

개체를 필요로 하는 클래스 내에서 직접 개체를 만드는 것은 클래스를 특정 개체에 커밋하고 나중에 클래스에서 독립적으로 인스턴스화를 변경할 수 없기 때문에 유연성이 떨어집니다(변경할 필요 없이).다른 오브젝트가 필요한 경우 클래스를 재사용할 수 없게 되고 실제 오브젝트를 모의 오브젝트로 대체할 수 없기 때문에 클래스를 테스트하기 어렵게 됩니다.

Abstract Factory 설계 패턴은 이러한 문제를 해결하는 방법을 설명합니다.

  • 개체 생성을 별도의(공장 출하시) 개체로 캡슐화합니다.즉, 오브젝트를 작성하기 위한 인터페이스(Abstract Factory)를 정의하고 인터페이스를 구현합니다.
  • 클래스는 오브젝트를 직접 작성하는 대신 팩토리 오브젝트에 오브젝트 작성을 위임합니다.

따라서 클래스는 오브젝트가 생성되는 방법(인스턴스화되는 구체적인 클래스)과 독립적입니다.클래스는 개체를 만드는 데 사용하는 팩토리 개체를 사용하여 구성할 수 있으며 런타임에 팩토리 개체를 교환할 수도 있습니다.

정의.

Abstract Factory Pattern의 본질은 "구체적인 [5]클래스를 지정하지 않고 관련 객체 또는 종속 객체의 패밀리를 작성하기 위한 인터페이스를 제공하는 것"입니다.

사용.

이 팩토리는 작성할 객체의 실제 유형을 결정하며, 여기서 객체가 실제로 작성됩니다(예를 들어 새로운 오퍼레이터에 의해 Java에서).그러나 공장에서는 생성된 구체적인 객체에 대한 추상 포인터만 반환합니다.

이를 통해 클라이언트는 팩토리 오브젝트원하는 추상 유형의 오브젝트를 생성하고 오브젝트에 [6]추상 포인터를 반환하도록 요구함으로써 클라이언트코드를 오브젝트 작성으로부터 보호합니다.

팩토리에서는 추상 포인터만 반환되므로 클라이언트 코드(팩토리로부터 오브젝트를 요구)는 방금 작성된 오브젝트의 실제 구체적인 유형을 알 수 없으며 이에 대한 부담도 없습니다.단, 콘크리트 객체(및 콘크리트 공장)의 유형은 추상 팩토리에 의해 알려져 있습니다.예를 들어 공장에서는 설정 파일에서 읽을 수 있습니다.컨피규레이션파일에 이미 지정되어 있기 때문에, 클라이언트는 타입을 지정할 필요가 없습니다.특히, 이것은 다음을 의미합니다.

  • 클라이언트 코드에는 구체적인 유형에 대한 지식이 없으며 관련된 헤더 파일이나 클래스 선언을 포함할 필요가 없습니다.클라이언트 코드는 추상형만 취급합니다.구체적인 유형의 객체는 공장에서 실제로 생성되지만 클라이언트 코드는 추상 [7]인터페이스를 통해서만 이러한 객체에 액세스합니다.
  • 새로운 콘크리트 유형을 추가하려면 클라이언트 코드를 수정하여 다른 팩토리(일반적으로 한 파일에 한 줄씩 있는 수정)를 사용합니다.그런 다음 다른 팩토리는 다른 구체적인 유형의 개체를 만들지만 이전과 동일한 추상 유형의 포인터를 반환하므로 클라이언트 코드가 변경되지 않습니다.이것은 클라이언트코드를 수정하여 새로운 타입을 인스턴스화하는 것보다 훨씬 쉽습니다.이 경우 새로운 오브젝트가 생성되는 코드의 모든 위치를 변경해야 합니다(또한 구체적인 클래스 헤더 파일을 포함하여 그러한 모든 코드 위치에도 새로운 구체적인 타입에 대한 지식이 있어야 합니다).모든 팩토리 오브젝트가 싱글톤오브젝트에 글로벌하게 저장되어 모든 클라이언트코드가 싱글톤을 경유하여 오브젝트 작성을 위한 적절한 팩토리에 액세스 하는 경우 팩토리 변경은 싱글톤오브젝트를 변경하는 [7]것만큼 간단합니다.

구조.

UML 다이어그램

Class diagram example The method createButton on the GUIFactory interface returns objects of type Button. What implementation of Button is returned depends on which implementation of GUIFactory is handling the method call.
클래스 다이어그램 예제 방법createButton에서GUIFactoryinterface가 유형의 개체를 반환합니다.Button의 어떤 실장Button반환되는 것은, 의 실장에 의해서 다릅니다.GUIFactory는 메서드 콜을 처리하고 있습니다.
A sample UML class and sequence diagram for the Abstract Factory design pattern. [8]
Abstract Factory 설계 패턴의 샘플 UML 클래스 및 시퀀스 다이어그램.[8]

위의 UML 클래스 다이어그램에서는Client필요한 클래스ProductA그리고.ProductB오브젝트에서는, 의 인스턴스가 행해지지 않습니다.ProductA1그리고.ProductB1직접 수업할 수 있습니다.대신,Client를 참조합니다.AbstractFactory오브젝트를 작성하기 위한 인터페이스.Client오브젝트 작성 방법(인스턴스되는 구체적인 클래스)과는 무관합니다.Factory1class는 다음 명령을 실행합니다.AbstractFactory인터페이스, 즉,ProductA1그리고.ProductB1반.
UML 시퀀스 다이어그램은 런타임 상호 작용을 보여 줍니다.Client오브젝트 콜createProductA()에서Factory1object를 생성하여 반환한다.ProductA1물건.그 후,ClientcreateProductB()Factory1를 생성하여 반환한다.ProductB1물건.

LePUS3 관리도

legend
범례

Python 예시

부터 abc 수입품 ABC, 추상적 방법 부터 시스템 수입품 플랫폼   학급 단추(ABC):     @http 방법     방어하다 페인트(자신):         통과하다   학급 Linux 버튼(단추):     방어하다 페인트(자신):         돌아가다 "Linux 스타일로 버튼 렌더링"   학급 윈도 버튼(단추):     방어하다 페인트(자신):         돌아가다 "Windows 스타일로 단추 렌더링"   학급 MacOSButton(단추):     방어하다 페인트(자신):         돌아가다 "MacOS 스타일로 버튼 렌더링"   학급 GUIFACTory(ABC):     @http 방법     방어하다 create_단추(자신):         통과하다   학급 Linux Factory(GUIFACTory):     방어하다 create_단추(자신):         돌아가다 Linux 버튼()   학급 윈도 팩토리(GUIFACTory):     방어하다 create_단추(자신):         돌아가다 윈도 버튼()   학급 MacOS팩토리(GUIFACTory):     방어하다 create_단추(자신):         돌아가다 MacOSButton()   한다면 플랫폼 == "리눅스":     공장  = Linux Factory() 엘리프 플랫폼 == "실패":     공장  = MacOS팩토리() 엘리프 플랫폼 == "win32":     공장  = 윈도 팩토리() 또 다른:     올리다 구현되지 않은 오류(f「사용의 플랫폼에는 실장되어 있지 않습니다.{플랫폼}")  단추 = 공장 .create_단추() 결과 = 단추.페인트() 인쇄물(결과) 

클래스 자체를 공장으로 사용하는 대체 구현:

부터 abc 수입품 ABC, 추상적 방법 부터 시스템 수입품 플랫폼   학급 단추(ABC):     @http 방법     방어하다 페인트(자신):         통과하다   학급 Linux 버튼(단추):     방어하다 페인트(자신):         돌아가다 "Linux 스타일로 버튼 렌더링"   학급 윈도 버튼(단추):     방어하다 페인트(자신):         돌아가다 "Windows 스타일로 단추 렌더링"   학급 MacOSButton(단추):     방어하다 페인트(자신):         돌아가다 "MacOS 스타일로 버튼 렌더링"   한다면 플랫폼 == "리눅스":     공장  = Linux 버튼 엘리프 플랫폼 == "실패":     공장  = MacOSButton 엘리프 플랫폼 == "win32":     공장  = 윈도 버튼 또 다른:     올리다 구현되지 않은 오류(f「사용의 플랫폼에는 실장되어 있지 않습니다.{플랫폼}")  단추 = 공장 () 결과 = 단추.페인트() 인쇄물(결과) 

「 」를 참조해 주세요.

레퍼런스

  1. ^ a b Freeman, Eric; Robson, Elisabeth; Sierra, Kathy; Bates, Bert (2004). Hendrickson, Mike; Loukides, Mike (eds.). Head First Design Patterns (paperback). Vol. 1. O'REILLY. p. 156. ISBN 978-0-596-00712-6. Retrieved 2012-09-12.
  2. ^ a b Freeman, Eric; Robson, Elisabeth; Sierra, Kathy; Bates, Bert (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.
  3. ^ Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 87ff. ISBN 0-201-63361-2.
  4. ^ "The Abstract Factory design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-11.
  5. ^ Gamma, Erich; Richard Helm; Ralph Johnson; John M. Vlissides (2009-10-23). "Design Patterns: Abstract Factory". informIT. Archived from the original on 2009-10-23. Retrieved 2012-05-16. Object Creational: Abstract Factory: Intent: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
  6. ^ Veeneman, David (2009-10-23). "Object Design for the Perplexed". The Code Project. Archived from the original on 2011-09-18. Retrieved 2012-05-16. The factory insulates the client from changes to the product or how it is created, and it can provide this insulation across objects derived from very different abstract interfaces.
  7. ^ a b "Abstract Factory: Implementation". OODesign.com. Retrieved 2012-05-16.
  8. ^ "The Abstract Factory design pattern - Structure and Collaboration". w3sDesign.com. Retrieved 2017-08-12.

외부 링크