본문 바로가기

취업과 기본기 튼튼/빽 투더 기본기

[디자인 패턴 5편] 생성 패턴, 추상 팩토리 메쏘드 (Abstract Factory)

1. 개념

추상 팩토리 메쏘드는, 기존 팩토리 메쏘드 방식에서
팩토리의 상위 팩토리를 통해 구체적인 팩토리를 생성한다.

1.1. 장점

  • 팩토리 메쏘드와 동일하다. 다만 팩토리의 종류가 늘었으므로, 커버 범위가 더 넓어졌다고 해야할까.
  • 객체의 생성을 한 군데에서 할 수 있다.

1.2. 단점

  • 팩토리 메쏘드와 동일하다.

1.3. 활용 상황

  • 팩토리 메쏘드를 쓰던 상황에서, 팩토리의 종류를 늘려야 할 때.

2. 구조

출처 : https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm

3. 코드

먼저 클라이언트는 다음과 같이 사용할 수 있다.

// AbstractFactoryPatternDemo.java

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
      // 팩토리의 팩토리인 FactoryProducer 를 통해 구체적인 팩토리 shapeFactory 를 얻습니다.
      AbstractFactory shapeFactory = FactoryProducer.getFactory(false);

      // shapeFactory 로 구체적인 Product 를 만듭니다. (팩토리 메쏘드와 동일)
      Shape shape1 = shapeFactory.getShape("RECTANGLE");
      shape1.draw();

      Shape shape2 = shapeFactory.getShape("SQUARE");
      shape2.draw();

      // 이번엔 FactoryProducer를 통해 구체적인 팩토리 shapeFactory1 을 얻습니다.
      AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);

      // 위와 동일하지만, 이번엔 shapeFactory1 로 Product 를 만듭니다.
      Shape shape3 = shapeFactory1.getShape("RECTANGLE");
      shape3.draw();
      Shape shape4 = shapeFactory1.getShape("SQUARE");
      shape4.draw();
   }
}

팩토리의 팩토리인 상위 팩토리는 추상 클래스로 다음과 같이 정의할 수 있다.

// AbstractFactory.java

public abstract class AbstractFactory {
   abstract Shape getShape(String shapeType) ;
}

구체적인 팩토리들은 이 추상 클래스를 상속받아 구현한다.

// ShapeFactory.java

public class ShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }     
      return null;
// RoundedShapeFactory.java

public class RoundedShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new RoundedRectangle(); // 위 팩토리와 이 부분이 다릅니다.         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new RoundedSquare(); // 위 팩토리와 이 부분이 다릅니다.
      }     
      return null;
   }
}

이렇게 만든 팩토리들은 다음 FactoryProudcer 를 통해 인스턴스로 만들어진다.

// FactoryProducer.java

public class FactoryProducer {
   public static AbstractFactory getFactory(boolean rounded){   
      if(rounded){
         return new RoundedShapeFactory();         
      }else{
         return new ShapeFactory();
      }
   }
}

4. 참고