_ 개발

[DESIGN PATTERN/JAVA] Factory Method - 팩토리 메서드 패턴

옴뇽뇽 2024. 11. 9. 18:10

 

목 차

Factory Method : 하위 클래스에서 인스턴스 작성하기

Factory Method 패턴의 구성 요소

Factory Method 패턴의 특징

Factory Method 패턴 구현 예시

Factory Method : 하위 클래스에서 인스턴스 작성하기

인스턴스 생성을 위한 공장(Factory)를 템플릿 메서드 패턴(Template Method)으로 구현한 디자인 패턴이다. 객체 생성 책임을 하위 클래스에 위임하여, 인스턴스를 생성할 때 어떤 클래스 인스턴스를 생성할지를 하위 클래스가 결정하게 한다. 객체 생성을 위해 직접 클래스의 인스턴스를 만들지 않고 특정 메서드를 호출하여 객체를 생성하도록 만든다.
 

Factory Method 패턴의 구성 요소

Factory Method 패턴 다이어그램

1. Product(제품) 인터페이스

  • Factory Method 패턴에서 생성될 인스턴스의 뼈대(인터페이스)를 결정하는 추상 클래스
  • 구체적인 내용은 ContreateProduct에서 결정

2. ConcreteProduct(구체적 제품)

  • Product를 상속받아 구현하는 실제 제품 객체 클래스

3. Factory(생산자) 인터페이스

  • 메서드 호출(factoryMethod)를 통해 Product 인스턴스를 생성하는 추상 클래스

4. ConcreteFactory(구체적 생산자)

  • Factory를 상속받아 구현하는 실제 생산자 클래스
  • 팩토리 메서드(factoryMethod)를 호출하여 구체적 제품(ConcreteProduct)을 생성

Factory Method 패턴의 특징

객체의 선택 및 생성의 유연성 & 확장의 용이

  • Product와 Factory를 이용해 다양한 제품(ConcreteProduct) 및 공장(ConcreteFactory)을 만들 수 있다.
  • 생성하려는 구체적인 제품과 공장이 달라진다고 할지라도 Product와 Creator가 수정될 필요없다. 클라이언트는 구현 클래스에 상관없이 Product와 Creator에 맞춰 코드를 작성하면 되고, 객체 타입이 변경이나 추가되더라도 클라이언트가 코드를 수정할 필요가 없다.

메서드 호출을 통한 인스턴스 생성

  • Factory에 Product 인스턴스 생성 메서드(factoryMethod)를 정의하여, 직접 클래스의 객체를 생성하는 대신 해당 메서드 호출을 통해 객체를 생성한다.
  • 인스턴스 생성의 구체적 로직은 하위 클래스 ConcreteFactory에서 구현하도록 한다.

Factory Method 패턴의 구현 예시 : 문서(Document)와 페이지(Page)

1. Product 인터페이스 역할: Page

abstract class Page {
    public abstract void printPageType();
}

2. ConcreteProduct 구현 클래스: IntroductionPage와 ContentPage

class IntroductionPage extends Page {
    @Override
    public void printPageType() {
        System.out.println("This is an Introduction Page.");
    }
}

class ContentPage extends Page {
    @Override
    public void printPageType() {
        System.out.println("This is a Content Page.");
    }
}

 

3. Creator 클래스 역할: Document

abstract class Document {
    public abstract Page createPage();

    public void printDocument() {
        Page page = createPage();
        page.printPageType();
    }
}
  • Document 클래스는 팩토리 메서드인 createPage를 통해 페이지를 생성하며, 이 메서드를 통해 어떤 페이지를 생성할지 구체적으로 정하지 않는다.

4. ConcreteCreator 구현 클래스: Book와 Magazine

class Book extends Document {
    @Override
    public Page createPage() {
        return new IntroductionPage();
    }
}

class Magazine extends Document {
    @Override
    public Page createPage() {
        return new ContentPage();
    }
}
  • Book과 Magazine 클래스에서 createPage 메서드가 각각 IntroductionPage와 ContentPage를 반환하도록 를 구현한다.

5. 클라이언트 코드

public class Main {
    public static void main(String[] args) {
        Document book = new Book();
        book.printDocument();  // "This is an Introduction Page." 출력

        Document magazine = new Magazine();
        magazine.printDocument();  // "This is a Content Page." 출력
    }
}

 

  • 클라이언트는 특정 페이지 객체를 생성하는 방식에 의존하지 않고, 단일한 메서드(printDocument)를 통해 필요한 페이지를 생성하고 사용할 수 있다.

Ref.

  • 책 『JAVA 언어로 배우는 디자인 패턴 입문: 쉽게 배우는 GoF의 23가지 디자인 패턴』 (저자 : 유키 히로시 저 / 번역 : 김성훈 역, 영진닷컴)