티스토리 뷰

728x90

 

 

 

1. Factory Method 패턴이란?

“구체 클래스를 명시하지 않고 객체를 생성할 수 있게, 생성 책임을 서브클래스로 넘기는 패턴” — GoF 정의

  • 패턴 분류 : GoF 23 패턴 중 Creational 범주.
  • 핵심 목적 : new 호출을 캡슐화하여 클라이언트‑코드 ↔ 제품‑구현 결합도를 낮추고, 확장 시 코드 수정 없이 새 제품을 투입할 수 있게 한다.
  • 적용 예 : JDBC DriverManager#getConnection()·로그 라이브러리의 LoggerFactory·Spring IoC의 BeanFactory 등이 모두 Factory Method를 응용한다.

2. 해결하고자 하는 문제

  1. 클래스 폭발 : 옵션마다 생성 로직이 달라 생성 코드가 곳곳에 흩어짐.
  2. OCP(Open‑Closed) 위반 : 새 제품 추가 때마다 if‑else 분기나 switch 수정이 필요.
  3. 테스트 어려움 : 직접 new를 호출하면 목(mock) 대체가 힘듦.
    → Factory Method는 생성 시점을 서브클래스에게 위임해 위 문제를 해소한다.

3. 구조(UML 관점)

역할 설명

Product 생성될 객체가 구현해야 할 인터페이스 (ex: Button)
ConcreteProduct 실제 제품 클래스 (ex: WindowsButton, MacButton)
Creator factoryMethod()를 선언. 기본 로직(템플릿) 안에서 이 메서드를 호출해 Product를 사용
ConcreteCreator factoryMethod()를 오버라이드해 원하는 ConcreteProduct를 반환

이 구조 덕분에 Creator 코드는 제품 종류를 전혀 모른 채 동작한다.


4. 자바 예제 코드

4‑1. Product 인터페이스 & 구체 제품

// Product
public interface Button {
    void render();
}

// ConcreteProductA
public class WindowsButton implements Button {
    public void render() {
        System.out.println("🪟 Windows 스타일 버튼");
    }
}

// ConcreteProductB
public class MacButton implements Button {
    public void render() {
        System.out.println("🍎 macOS 스타일 버튼");
    }
}

4‑2. Creator & ConcreteCreator

// Creator
public abstract class Dialog {
    // 템플릿 메서드
    public void show() {
        Button btn = createButton();   // 핵심: 팩토리 메서드!
        btn.render();
    }
    // Factory Method
    protected abstract Button createButton();
}

// ConcreteCreatorA
public class WindowsDialog extends Dialog {
    @Override
    protected Button createButton() {
        return new WindowsButton();
    }
}

// ConcreteCreatorB
public class MacDialog extends Dialog {
    @Override
    protected Button createButton() {
        return new MacButton();
    }
}

4‑3. 클라이언트 사용

public class Client {
    public static void main(String[] args) {
        Dialog dialog = System.getProperty("os.name").startsWith("Mac")
                         ? new MacDialog()
                         : new WindowsDialog();
        dialog.show();
    }
}
  • 확장성 : 새 OS 버튼을 추가할 때는 Button 구현 & Dialog 서브클래스만 만들면 된다—기존 클라이언트 수정 無.
  • 테스트 용이 : Dialog를 목 서브클래스로 대체해 createButton() 결과를 제어할 수 있다.

5. 장단점 정리

장점 단점

OCP·SRP 준수 → 신규 제품에 대한 코드 변경 최소화 클래스 수 증가(제품 + Creator)
클라이언트‑코드와 구체 클래스 분리 → 의존성 역전 가능 단순한 시나리오에서는 과공(Over‑Engineering) 위험
테스트·목킹 편리 여러 Creator 계층이 얽히면 추적 난이도 ↑

6. 실무 적용 포인트

  1. 조건 분기+생성 코드가 동시에 늘어날 때 고려.
  2. DI 컨테이너가 있더라도 런타임 파라미터에 따라 제품을 다르게 만들어야 하면 Factory Method가 유용하다. 예) 멀티‑테넌트에서 테넌트별 DAO 반환.
  3. 동시성: Creator가 상태를 갖지 않으면 싱글턴으로 둬도 무방하다.

7. Abstract Factory와의 비교

항목 Factory Method Abstract Factory

반환 범위 단일 제품 제품군(Kit)을 통째로 생성
구현 형태 메서드 단위 객체 단위(여러 Factory Method 포함)
사용 예 LoggerFactory#getLogger() DocumentBuilderFactory#newDocumentBuilder()

차이는 “메서드 vs 객체”, “제품 하나 vs 제품군”에 있다.


8. 결론

Factory Method 패턴은 “객체 생성 로직을 한 단계 위임”함으로써 결합도를 낮추고, 기능 확장·테스트 용이성·유지보수를 개선한다. 하지만 ‘복잡도 대비 효과’를 냉정히 따져 단순 CRUD 앱처럼 제품 종류가 늘 변하지 않는 상황엔 과용을 피하자. 패턴은 필요할 때 — 특히 “클래스 선택이 자주 변하거나 런타임 조건으로 나뉠 때” — 가장 큰 가치를 발휘한다.

 

 

728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함