theory/디자인패턴

GoF의 디자인 패턴. 생성패턴 3. 팩토리 메서드

아르르르를를르 2021. 8. 22. 14:31

- 지난 글에 이어 생성패턴을 다뤄본다.

추상 팩토리 (Abstract Factory)

빌더 (Builder)

팩토리 메서드 (Factory Methods)

프로토타입 (Prototype)

싱글턴 (Singleton)

 

 


팩토리 메서드 (Factory Methods)

- 의도

객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성하지에 대한 결정은 서브클래스가 내리도록 한다.

 

- 동기

객체를 "제조하는" 방법을 아는 연산을 분리한다.

 

- 활용성

  • 어떤 클래스가 자신이 생성해야 하는 객체의 클래스를 예측할 수 없을 때
  • 생성할 객체를 기술하는 책임을 자신의 서브클래스가 지정했으면 할 때
  • 객체 생성의 책임을 몇 개의 보조 서브클래스 중 하나에 위임, 어떤 서브클래스가 위임자인지에 대한 정보를 국소화시키고 싶을 때

 

- 구조

 

- 참여자

  • Product: 팩토리 메서드가 생성하는 개체의 인터페이스 정의
  • ConcreteProduct: Product 클래스에 정의도니 인터페이스를 실제로 구현
  • Creator: Product 타입의 객체를 반환하는 팩토리 메서드를 선언. Creator 클래스는 팩토리 메서드를 구현하며 ConcreteProduct 객체를 반환
  • ConcreteCreator: 팩토리 메서드를 재정의하여 ConcreteProduct의 인스턴스를 반환

 

- 결과

  • 서브클래스에 대한 hook 메서드 제공
    • 객체별로 서로 다른 버전을 제공하는 hook 기능을 서브클래스에 정의 가능
  • 병렬적인 클래스 계통 연결하는 역할 담당
    • ex) TextManipulator, LineManipulator 등

 

- 구현

  1. 두가지 방법이 있다.
    1. Creator 클래스를 추상 클래스로 정의, 팩토리 메서드 기본 구현 제공하지 않음
    2. Creator 클래스를 구체 클래스로 정의, 팩토리 메서드 기본 구현 제공
  2. 팩토리 메서드를 매게변수화
    1. public static Product Creator(Product Id){
          if(id == MINE) return new MyProduct;
          else if(id == YOURS) return new YourProduct;
          ..
          return defaultProduct;
      }
  3. 템플릿을 사용하여 서브클래싱 회피 가능

 

- 예제

도형 그리는 작업을 예시로 든다.

 

Shape.java

public interface Shape {
	void draw();
}

 

Circle.java

public class Circle implements Shape {
    @Override
    public void draw(){
        System.out.println("Draw Circle!");
    }
}

 

Rectangle.java

public class Rectangle implements Shape {
	@Override
    public void draw(){
    	System.out.println("Draw Rectangle!");
    }
}

 

Square.java

public class Square implements Shape {
	@Override
    public void draw(){
    	System.out.println("Draw Square!");
    }
}

 

ShapeFactory.java

public class ShapeFactory{

	public Shape getShape(String shapeType){
        if(shapeType == null){
            return null;
        }
        if(shapeType.equalsIgnoreCase("CIRCLE")){
            return new Circle();
        } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
            return new Rectangle();
        } else if(shapeType.equalsIgnoreCase("SQUARE")){
            return new Square();
        }
    }
    return null;
}

 

FactoryPatternTest.java

public class FactoryPatternTest {
	public static void main(String[] args){
        ShapeFactory shapeFactory = new ShapeFactory();
        
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();
        
        Shape shape2 = shapeFactory.getShape("RECTANGLE");
        shape2.draw();
        
        Shape shape3 = shapeFactory.getShape("SQUARE");
        shape3.draw();
    }
}


// 출력 결과
// Draw Circle!
// Draw Rectangle!
// Draw Square!

 

- 참고 문헌

  • GoF의 디자인 패턴(개정판) / 에릭 감마, 리처드 헬름, 랄프 존슨, 존 블라시디스 공저 / 김정아 역 / 프로텍미디어 / 발행 2015년 03월 26일
  • https://niceman.tistory.com/143