팩토리 메서드 패턴 (Factory Method Pattern)

한눈에 보기

객체 생성 인터페이스를 상위 클래스에 정의하고 어떤 인스턴스를 만들지는 하위 클래스가 결정하는 생성 패턴이다. 추상 팩토리, 단순 팩토리와의 차이를 비교표로 정리한다.

최종 업데이트 2026.09.17

팩토리 메서드 패턴(Factory Method Pattern)은 객체 생성을 위한 인터페이스를 상위 클래스에 정의하고, 실제로 어떤 클래스의 인스턴스를 만들지는 하위 클래스가 결정하도록 미루는 생성 디자인 패턴이다. 팩토리 메서드 패턴을 적용하면 객체를 사용하는 코드와 객체를 생성하는 코드가 분리되어, 새로운 제품 타입이 추가되어도 기존 로직을 수정하지 않고 확장할 수 있다.

패턴의 의도

코드 곳곳에 new 구체클래스()가 흩어져 있으면 두 가지 문제가 생긴다. 첫째, 사용하는 쪽이 구체 클래스에 직접 의존하므로 새로운 종류의 객체가 추가될 때마다 생성 지점을 전부 찾아 수정해야 한다. 둘째, 생성 로직이 복잡해지면(설정 읽기, 유효성 검사, 초기화 순서 등) 그 복잡함이 사용하는 코드까지 오염시킨다.

팩토리 메서드 패턴은 "무엇을 만들지 아는 책임"을 하위 클래스로 밀어낸다. 상위 클래스는 객체를 만들어 사용하는 전체 흐름만 정의하고, 생성 지점은 추상 메서드(팩토리 메서드)로 뚫어 둔다. 하위 클래스가 이 메서드를 오버라이드해 구체 제품을 반환하면, 상위 클래스의 로직은 어떤 제품이 오든 인터페이스만 보고 동작한다. 결국 생성의 변화가 하위 클래스 추가라는 형태로 격리된다.

구조와 참여 객체

  • 제품(Product): 팩토리 메서드가 반환하는 객체들의 공통 인터페이스다.
  • 구체 제품(Concrete Product): 제품 인터페이스의 실제 구현체다.
  • 생성자(Creator): 팩토리 메서드를 추상 메서드로 선언하고, 제품을 활용하는 공통 로직을 담는 클래스다. 이 클래스의 핵심 역할은 생성이 아니라 제품을 사용하는 비즈니스 로직이라는 점에 주의한다.
  • 구체 생성자(Concrete Creator): 팩토리 메서드를 오버라이드하여 특정 구체 제품을 생성해 반환한다.

흐름을 정리하면, 클라이언트는 구체 생성자를 골라 인스턴스화하고, 생성자의 공통 로직이 실행되는 중간에 팩토리 메서드가 호출되어 하위 클래스가 정한 제품이 만들어진다. 상위 클래스 입장에서는 생성이 다형성의 한 지점이 된 것이다.

Java 코드 예시

알림 발송 기능을 예로 든다. 발송 전후의 로깅과 재시도 같은 공통 흐름은 상위 클래스에 있고, 어떤 채널의 알림 객체를 만들지는 하위 클래스가 정한다.

// 제품 인터페이스
public interface Notification {
    void send(String message);
}

// 구체 제품
public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("이메일 발송: " + message);
    }
}

public class SmsNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS 발송: " + message);
    }
}

// 생성자: 공통 흐름 + 팩토리 메서드 선언
public abstract class NotificationService {

    // 제품을 사용하는 공통 로직
    public void notifyUser(String message) {
        Notification notification = createNotification(); // 팩토리 메서드 호출
        System.out.println("발송 시작");
        notification.send(message);
        System.out.println("발송 완료 기록");
    }

    // 팩토리 메서드: 생성 책임을 하위 클래스에 위임
    protected abstract Notification createNotification();
}

// 구체 생성자
public class EmailNotificationService extends NotificationService {
    @Override
    protected Notification createNotification() {
        return new EmailNotification();
    }
}

// 클라이언트
NotificationService service = new EmailNotificationService();
service.notifyUser("면접 일정이 확정되었습니다");

푸시 알림이 새로 필요해지면 PushNotification과 PushNotificationService를 추가하면 끝이다. NotificationService의 공통 흐름은 한 글자도 바뀌지 않으므로 개방 폐쇄 원칙이 지켜진다.

장단점과 사용 시점

장점은 생성 코드와 사용 코드의 결합이 끊어진다는 것이다. 사용하는 쪽은 제품 인터페이스에만 의존하므로 구체 클래스 교체와 추가가 자유롭고, 생성 로직이 한 곳에 모여 관리와 테스트가 쉬워진다. 테스트에서는 가짜 제품을 반환하는 테스트용 구체 생성자를 만들어 외부 의존 없이 공통 흐름을 검증할 수 있다.

단점은 제품 하나를 추가할 때마다 생성자 하위 클래스도 함께 만들어야 해서 클래스 수가 빠르게 늘어난다는 점이다. 제품 종류가 적고 생성 로직이 단순하다면 단순 팩토리(정적 메서드에서 switch로 분기하는 방식)나 Java 8 이후의 Supplier 주입이 더 실용적일 수 있다. 패턴이 필요한 시점은 생성할 타입이 계속 늘어날 것이 예상되고, 생성 전후로 공통 로직이 존재하며, 사용하는 코드가 구체 타입을 몰라야 하는 경우다.

용어 혼동도 짚고 넘어가야 한다. List.of나 Optional.of처럼 생성자를 대신하는 정적 팩토리 메서드(static factory method)는 이름에 팩토리가 들어가지만 GoF의 팩토리 메서드 패턴이 아니다. GoF 패턴의 핵심은 상속과 오버라이드를 통한 다형적 생성이고, 정적 팩토리 메서드는 이름 있는 생성 함수라는 관용 기법이다. 면접에서 두 개념을 섞어 말하면 감점 요인이 되므로 구분해서 답해야 한다.

유사 패턴과 비교

구분팩토리 메서드추상 팩토리(Abstract Factory)단순 팩토리(Simple Factory)
생성 대상제품 한 종류서로 관련된 제품군 여러 개제품 한 종류
확장 방식상속(하위 클래스가 결정)팩토리 객체 교체(합성)분기문 수정
OCP 준수준수(클래스 추가로 확장)준수(팩토리 추가로 확장)미준수(기존 코드 수정 필요)
GoF 패턴 여부맞다맞다아니다(관용적 기법)

추상 팩토리는 버튼, 체크박스, 창처럼 함께 쓰여야 하는 제품군 전체를 일관되게 생성하는 데 초점이 있고, 내부의 각 생성 메서드가 팩토리 메서드로 구현되는 경우가 많다. 템플릿 메서드 패턴과의 관계도 자주 언급되는데, 팩토리 메서드는 "생성 단계"를 하위 클래스에 위임하는 템플릿 메서드의 특수한 형태로 볼 수 있다.

면접에서 이렇게 물어본다

  • 팩토리 메서드 패턴이 해결하는 문제를 new 키워드 직접 사용의 단점과 연결해 설명해 보라.
  • 팩토리 메서드 패턴과 추상 팩토리 패턴의 차이는 무엇인가.
  • 단순 팩토리(정적 팩토리 + 분기문)와 비교했을 때 팩토리 메서드 패턴이 개방 폐쇄 원칙 측면에서 갖는 이점은 무엇인가.
  • 팩토리 메서드 패턴의 단점(클래스 수 증가)을 완화할 수 있는 현대적인 대안을 알고 있는가.
  • 팩토리 메서드 패턴이 템플릿 메서드 패턴과 구조적으로 어떤 관계인지 설명해 보라.
디자인 패턴 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기