본문 바로가기
Programming/DesignPattern

[디자인 패턴] 추상 팩토리(Abstract Factory) 패턴

by Blemish 2021. 6. 3.

Goal

  • 추상 팩토리 패턴을 이해한다.

 

추상 팩토리(Abstract Factory) 패턴

 

 관련성 있고 서로 의존적인 여러 종류의 객체를 일관성 있는 방식으로 생성할 때 유용한 패턴

클래스 다이어그램

  • AbstractFactory : 실제 팩토리 클래스의 공통 인터페이스, 각 제품의 부품을 생성하는 기능을 추상 메서드로 정의
  • ConcreteFactory : 구제적인 팩토리 클래스로 AbstractFactory 클래스의 추상 메서드를 오버라이드함으로써 구체적인 제품을 생성
  • AbstractProduct : 제품의 공통 인터페이스
  • ConcreteProduct : 구체적인 팩토리 클래스에서 생성되는 구체적인 제품

※ 팩토리 메서드 패턴과 추상 팩토리 패턴은 엄연히 다르다. 

 팩토리 메서드 패턴은 객체를 생성하는 코드를 별도의 클래스/메서드로 분리해 캡슐화하는 패턴이고 추상 팩토리 패턴은 관련성 있는 여러 종류의 객체들을 일관성 있는 방식으로 생성할 때 사용하는 패턴이다.

 

Example

엘리베이터를 구성하는 부품중에서 모터와 문을 업체에 맞게 제공하는 기능을 구현해보자

 

여러 제조 업체중에서 기아와 한화에 대해서만 생각해보자. 기아는 기아 모터와 기아 문을 제공하고 한화는 한화 모터와 한화 문을 제공할 것이다.

 우선 기아 모터와 한화 모터는 구체적인 제어 방식은 다르지만 모터를 구동해서 엘리베이터를 이동시킨다는 점은 동일하다. 그리고 문의 경우에는 두 업체가 동일한 방식으로 움직이지만 구체적인 제어 방식은 조금씩 다를 수 있다. 따라서 모터와 문에 대한 공통적인 기능을 먼저 정의해야 한다.

클래스 다이어그램

각 업체는 모터와 문에 대한 공통적인 기능을 먼저 정의한 다음 세부적인 기능은 각 업체의 세부 클래스에서 정의한다.

공통되는 기능을 Motor, Door 클래스에 정의하고 세부적인 기능은 GIAMotor, HanwhaMotor, GIADoor, HanwhaDoor 클래스에 정의한다. 또한 세부적인 기능을 담당하는 클래스들은 공통되는 기능을 담당하는 클래스들과 일반화 관계이고 Motor 클래스에서 Door 클래스로의 연관관계를 정의했다. 

 객체의 생성 방식은 팩토리 메서드 패턴과 동일하게 적용하면 되기 때문에 각 부품에 대한 팩토리 클래스를 구현해야 한다.

 

클래스 다이어그램

위의 클래스 다이어그램은 팩토리 메서드 패턴을 적용해 설계하여 작성한 클래스 다이어그램이다.

각 부품에 대한 팩토리 메서드를 설계하였고 이제 클라이언트에서 팩토리 클래스들을 이용해 각 부품들에 대한 클래스 객체를 사용하면 된다.

 

 

Door 클래스와 Motor 클래스는 템플릿 메서드 패턴을 사용하였고 Motor 클래스에서 hook 메서드(MoveMotor)를 정의하였고 Door 클래스에서 hook 메서드(DoOpen, DoClose)를 정의하였다.

팩토리 클래스에서는 VendorID를 이용하여 GIA, Hanwha 부품 객체를 생성할 수 있도록 구현하였다.

클라이언트에서 Factory 클래스를 이용해 GIAMotor, GIADoor 객체를 사용하여 엘리베이터를 움직인다.

 

Question

  • 현재 코드는 GIA의 부품을 사용한다. 만약 새로운 부품을 사용해야 한다면?(센서, 음성인식 등)                            ->추가된 부품에 대한 Factory 클래스를 구현하고 이들의 Factory 객체를 각각 생성해야 한다. 따라서 추가된 부품이 많아질수록 구현해야 할 Factory 클래스가 많아진다.
  • 새로운 제조 업체의 부품을 지원해야 한다면?(삼성의 부품을 지원해야 한다면?)                                                  ->  MotorFactory, DoorFactory에서 각각 Samsung 부품을 지원할 수 있도록 수정해야 한다

 

엘리베이터는 특정 모터와 특정 문을 제어할 필요가 있다. 일반적으로는 기아 모터를 사용하면 기아 문을 사용하고 한화 모터를 사용하면 한화 문을 사용할 것이다. 이와 같이 여러 종류의 객체를 생성할 때 객체들 사이의 관련성이 있는 경우라면 각 종류별로 별도의 Factory 클래스를 사용하는 대신 관련 객체들을 일관성 있게 생성하는 Factory 클래스를 사용하는 것이 편리할 수 있다.

 

 

클래스 다이어그램

 

이전 방식과 다르게 이번에는 HanwhaFactory에서 Hanwha Motor, Door 객체를 생성한다. 또한 GIAFactory에서 GIA Motor, Door 객체를 생성한다. 즉 엘리베이터를 구성하는 부품의 객체를 생성하는 메서드가 공통으로 있다.

그러므로 각 Factory 클래스를 일반화한 상위 클래스를 정의할 수 있다.

 

ElevatorFactory는 추상 클래스이고 CreateMotor와 CreateDoor도 추상 메서드로 정의되었다.

이제는 새롭게 브랜드가 추가되면 그 브랜드 클래스만 새롭게 만들면 된다.

VendorID에 Samsung을 새롭게 추가하였다.

SamsungFactory를 새롭게 추가하였고 부품 클래스인 SamsungMotor와 SamsungDoor를 새롭게 추가하였다.

 

ElevatorFactory 클래스 객체를 생성할 수 있는 클래스를 구현하였다. 이 때 메모리 낭비를 방지하기 위해 Singleton 패턴을 사용하였다.

 

 

댓글