티스토리 뷰

팩토리 메소드 패턴이란?

팩토리 메소드 패턴은 객체를 생성하는 코드를 공장 클래스로 별도의 클래스로 분리해 캡슐화 처리한 패턴이다. 즉, 클라이언트에서 직접 new 연산자를 통해 제품 객체를 생성하는 것이 아닌, 인스턴스화를 서브클래스에 미룬 것이다. 클라이언트는 제품 객체를 생성하는 공장 클래스를 만들고, 이를 상속하는 서브 공장 클래스의 메서드에서 여러가지 제품 객체 생성을 각각 책임지는 것이다.  

팩토리 메소드 패턴 사용 법

  • Creator : 최상위 공장 클래스로서, 팩토리 메서드를 추상화하여 서브 클래스로 하여금 구현하도로 함
    • 객체 생성 처리 메서드(someOperartion) : 객체 생성에 관한 전처리, 후처리를 템플릿화한 메소드
    • 팩토리 메서드(createProduct) : 서브 공장 클래스에서 재정의할 객체 생성 추상 메서드
  • ConcreteCreator : 각 서브 공장 클래스들은 이에 맞는 제품 객체를 반환하도록 생성 추상 메소드를 재정의한다. 즉, 제품 객체 하나당 그에 걸맞는 생산 공장 객체가 위치된다. 예를 들어 ConcreteCreatorA는 ConcreteProductA를 생성하고, ConcreteCreatorB는 ConcreteProductB를 생성하는 식이다.
  • Product : 제품 구현체를 추상화
  • ConcreteProduct : 제품 구현체
정리하자면, 팩토리 메소드 패턴은 객체를 만들어내는 공장(Factory 객체)을 만드는 패턴이라고 보면 된다. 그리고 어떤 클래스의 인스턴스를 만들지는 미리 정의한 공장 서브 클래스에서 결정한다.
// 제품 객체 추상화 (인터페이스)
interface Product {
    void doStuff();
}

// 제품 구현체
class ConcreteProductA implements IProduct {
    public void doStuff() {
    }
}

class ConcreteProductB implements IProduct {
    public void doStuff() {
    }
}

 

// 공장 객체 추상화 (추상 클래스)
abstract class Creator {

    // 객체 생성 전처리 후처리 메소드 (final로 오버라이딩 방지, 템플릿화)
    final Product createOperation() {
        Product product = createProduct(); // 서브 클래스에서 구체화한 팩토리 메서드 실행
        product.doStuff(); // .. 이밖의 객체 생성에 가미할 로직 실행
        return product; // 제품 객체를 생성하고 추가 설정하고 완성된 제품을 반환
    }

    // 팩토리 메소드 : 구체적인 객체 생성 종류는 각 서브 클래스에 위임
    // protected 이기 때문에 외부에 노출이 안됨
    abstract protected Product createProduct();
    
    void someOperation(){};
}

// 공장 객체 A (ProductA를 생성하여 반환)
class ConcreteCreatorA extends AbstractFactory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

// 공장 객체 B (ProductB를 생성하여 반환)
class ConcreteCreatorB extends AbstractFactory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}
class Client {
    public static void main(String[] args) {
        // 1. 공장 객체 생성 (리스트)
        Creator[] factory = {
                new ConcreteCreatorA(),
                new ConcreteCreatorB()
        };

        // 2. 제품A 생성 (안에서 createProduct() 와 생성 후처리 실행)
        Product productA = factory[0].createOperation();

        // 3. 제품B 생성 (안에서 createProduct() 와 생성 후처리 실행)
        Product productB = factory[1].createOperation();
    }
}

패턴 사용 시기

  • 클래스 생성과 사용의 처리 로직을 분리해 결합도를 낮추고자 할 때
  • 코드가 동작해야 하는 객체의 유형과 종속성을 캡슐화를 통해 정보 은닉 처리할 경우
  • 라이브러리 혹은 프레임워크 사용자에게 구성 요소를 확장하는 방법을 제공하려는 경우
  • 기존 객체를 재구성하는 대신 기존 객체를 재사용하여 리소스를 절약하고자 하는 경우
    • 상황에 따라 적절한 객체를 생성하는 코드는 자주 중복될 수 있다. 그리고 객체 생성 방식의 변화는 해당되는 모든 코드 부분을 변경해야 하는 문제가 발생한다.
    • 따라서 객체의 생성 코드를 별도의 클래스, 메서드로 분리함으로써 객체 생성의 변화에 대해 대비를 하기 위해 팩토리 메서드 패턴을 이용한다.

패턴 장점

  • 생성자(Creator)와 구현 객체(Concrete Product)의 강한 결합을 피할 수 있다.
  • 객체의 생성 후 공통으로 할 일을 수행하도록 지정해줄 수 있다.
  • 캡슐화, 추상화를 통해 생서되는 객체의 구체적인 타입을 감출 수 있다.
  • 단일 책임의 원칙 준수: 객체 생성 코드를 한 곳으로 이동하여 코드를 유지보수하기 쉽게 할 수 있다.
  • OCP 원칙 준수: 기존 코드를 수정하지 않고 새로운 유형의 제품 인스턴스를 프로그램에 도입할 수 있어 원칙을 만족한다.

패턴 단점

  • 각 제품 구현체마다 팩토리 객체들을 모두 구현해주어야 하므로 구현체가 늘어날 때마다 팩토리 클래스가 증가해 서브 클래스 수가 증가한다. 
  • 코드의 복잡성이 증가한다.

코드

 

💠 팩토리 메서드(Factory Method) 패턴 - 완벽 마스터하기

Factory Method Pattern 팩토리 메소드 패턴은 객체 생성을 공장(Factory) 클래스로 캡슐화 처리하여 대신 생성하게 하는 생성 디자인 패턴이다. 즉, 클라이언트에서 직접 new 연산자를 통해 제품 객체를

inpa.tistory.com