inblog logo
|
DailyCoding
    Spring Boot

    13-9. 팩토리 패턴 (Factory Pattern)

    박은서's avatar
    박은서
    Feb 25, 2026
    13-9. 팩토리 패턴 (Factory Pattern)
    Contents
    1. 팩토리 패턴 (Factory Pattern)1️⃣ 팩토리 패턴이란?2️⃣ 사용 이유3️⃣ 기본 구조4️⃣ 예시5️⃣ 팩토리 패턴의 장단점6️⃣ 언제 사용?7️⃣ 핵심 목적 🚨2. 실습 (ex09)1️⃣ 실습2️⃣ 실행 흐름 따라가기

    1. 팩토리 패턴 (Factory Pattern)

    1️⃣ 팩토리 패턴이란?

    1) 정의

    객체 생성 로직을 별도의 Factory에 위임하는 생성 패턴
    ✔ 객체 생성 책임 분리
    ✔ 결합도 감소 목적

    2) 핵심 개념

    “new를 직접 쓰지 않는다”
    Animal animal = AnimalFactory.create("dog");
    ✔ 생성 → Factory 담당
    ✔ 사용 → Client 담당

    2️⃣ 사용 이유

    1) 기존 방식 문제

    ❌ new 남발
    ❌ 생성 방식 변경 시 수정 범위 큼
    ❌ 조건문 증가
    ❌ 결합도 상승

    2) 팩토리 적용 효과

    ✔ 생성 로직 중앙화
    ✔ 변경 영향 최소화
    ✔ 확장 용이

    3️⃣ 기본 구조

    1) Product (인터페이스 / 추상 클래스)

    • 역할 : 객체의 공통 규격 정의
      • 객체들이 따라야 할 타입
      • 클라이언트가 의존하는 대상
      • 구현체 교체 가능하게 만드는 핵심
    • 핵심 키워드 : “무엇을 할 수 있는가 정의”
    interface Animal { void speak(); }

    2) ConcreteProduct (구현 클래스)

    • 역할 : 실제 객체 구현
      • Product 규격 구현
      • 실제 동작 수행
      • Factory에 의해 생성됨
    • 핵심 키워드 : “실제 기능 제공”
    class Dog implements Animal { } class Cat implements Animal { }

    3) Factory (생성 담당 클래스)

    • 역할 : 객체 생성 책임 담당
      • 객체 생성 로직 캡슐화
      • 어떤 객체 만들지 결정
      • 클라이언트의 new 제거
    • 핵심 키워드 : “객체 생성 전담”
    Animal animal = AnimalFactory.create("dog");

    4️⃣ 예시

    1) Product

    interface Animal { void speak(); }

    2) ConcreteProduct

    class Dog implements Animal { } class Cat implements Animal { }

    3) Factory

    class AnimalFactory { public static Animal create(String type) { if (type.equals("dog")) return new Dog(); if (type.equals("cat")) return new Cat(); throw new IllegalArgumentException(); } }

    4) Client

    Animal animal = AnimalFactory.create("dog");
    ✔ 구체 클래스 의존 제거

    5️⃣ 팩토리 패턴의 장단점

    1) 장점

    • Loose Coupling (결합도 감소)
    • 생성 로직 캡슐화
    • 확장성 증가 (OCP 준수)
    • 객체 생성 정책 관리 용이

    2) 단점

    • ❌ Factory 클래스 비대화 가능
    • ❌ 조건문 증가 가능
    • ❌ 단순한 경우 과설계

    6️⃣ 언제 사용?

    • 생성 과정 복잡
    • 객체 종류 많음
    • 조건 기반 객체 생성
    • 생성 정책 변경 가능성 높음
    • 예
      • DB 객체 생성
      • UI 컴포넌트
      • 로깅 시스템
      • 게임 캐릭터

    7️⃣ 핵심 목적 🚨

    • ❌ new 숨기기 아님 → ✅ 객체 생성 책임 분리

    2. 실습 (ex09)

    1️⃣ 실습

    1) DB.java (인터페이스)

    C:\workspace\java_lab\designapp\src\ex09\lib\DB.java
    package ex09.lib; public interface DB { void setUrl(String url); int execute(String sql); }
    • 역할
      • 모든 DB 클래스의 공통 규칙 (표준 스펙)
      • “DB라면 반드시 이 기능을 구현해야 함”
    • 목적
      • App은 구체 클래스 몰라도 됨
        • MariaDB인지 OracleDB인지 관심 없음!
        • DB 타입이면 OK!
    → 다형성의 기반

    2) Driver.java (enum - 열거형)

    C:\workspace\java_lab\designapp\src\ex09\lib\Driver.java
    package ex09.lib; public enum Driver { ORACLE("oracle"), MARIA("maria"); private final String protocol; Driver(String protocol) { this.protocol = protocol; } public String getProtocol() { return protocol; } }
    • 역할
      • DB 종류를 표현하는 식별자
      • 문자열 하드코딩 방지
      • 타입 안정성 확보
    • 목적
      • Factory에게 전달하는 선택값
      • 어떤 DB 만들지 알려주는 신호

    3) MariaDB.java (구현 클래스)

    C:\workspace\java_lab\designapp\src\ex09\lib\MariaDB.java
    package ex09.lib; public class MariaDB implements DB { private String path; @Override public int execute(String sql) { if (path == null) { System.out.println("path : null point error"); return -1; } if (sql.equals("select")) { System.out.println("query execute : " + path + "/" + sql); return 1; } else { System.out.println("query fail : syntax error"); return -1; } } @Override public void setUrl(String path) { this.path = path; } }
    • 역할
      • 실제 DB 동작 구현
      • execute(), setUrl() 구체 로직 담당
    • 특징
      • MariaDB 방식으로 동작
      • SQL 처리 방식 정의
      • ➡️ 인터페이스 계약 이행

    4) OracleDB.java (구현 클래스)

    C:\workspace\java_lab\designapp\src\ex09\lib\OracleDB.java
    package ex09.lib; public class OracleDB implements DB { public String url; @Override public int execute(String sql) { if (sql.equals("select")) { System.out.println("query execute : " + url + "/" + sql); return 1; } else { System.out.println("query fail : syntax error"); return -1; } } @Override public void setUrl(String url) { this.url = url; } }
    • 역할
      • Oracle 전용 DB 동작 구현
      • MariaDB와 동일한 인터페이스 사용
    • 목적
      • DB 인터페이스 기반 다형성 실현

    5) DBFactory.java (핵심)

    C:\workspace\java_lab\designapp\src\ex09\DBFactory.java
    package ex09; import ex09.lib.DB; import ex09.lib.Driver; import ex09.lib.MariaDB; import ex09.lib.OracleDB; public class DBFactory { private static DBFactory instance = new DBFactory(); public DBFactory() {} public static DBFactory getInstance() { return instance; } // 단점 : OCP 위배 (새로운 DB 추가해야 할 경우, 이 코드를 수정해야 함) public DB creatDB(Driver driver) { if (driver.getProtocol().equals("maria")) { MariaDB mariaDB = new MariaDB(); mariaDB.setUrl("jdbc:mariadb://127.0.0.1:3306"); return mariaDB; } else if (driver.getProtocol().equals("oracle")) { OracleDB oracleDB = new OracleDB(); oracleDB.setUrl("jdbc:oracle:thin://127.0.0.1:8080"); return oracleDB; } else { throw new NullPointerException("DB driver not found exception"); } } }
    • 역할 (가장 중요 ⭐⭐⭐)
      • 객체 생성 담당
      • 어떤 DB 객체 만들지 결정
      • 초기화(setUrl)까지 처리
    • 책임
      • 객체 생성 책임 집중
      • App에서 제거된 코드(new MariaDB(), new OracleDB())를 Factory가 대신 수행

    6) App.java

    C:\workspace\java_lab\designapp\src\ex09\App.java
    package ex09; import ex09.lib.DB; import ex09.lib.Driver; /** * 팩토리 패턴 예제 */ public class App { public static void main(String[] args) { DBFactory factory = DBFactory.getInstance(); DB db = factory.creatDB(Driver.MARIA); // 팩토리에게 요청! db.execute("select"); } }
    • 역할
      • 프로그램 시작점
      • Factory에게 요청만 함
      • DB 사용만 담당
    • 특징
      • 생성 로직 모름
      • DB 종류 변경 영향 최소화
      • ➡️ 의존성 감소

    2️⃣ 실행 흐름 따라가기

    ▶ 1단계: App 시작

    DBFactory factory = DBFactory.getInstance();
    App.java
    ➡️ 싱글톤 Factory 객체 가져옴
    ⚠️ 이미 DBFactory 내부에 생성되어 있음
    private static DBFactory instance = new DBFactory();
    DBFactory.java

    ▶ 2단계: DB 생성 요청

    DB db = factory.creatDB(Driver.MARIA);
    App.java
    App “나는 어떤 DB인지 관심 없음. MARIA 드라이버니까 알아서 만들어줘”

    ▶ 3단계: Factory 내부 동작 ⭐

    public DB creatDB(Driver driver)
    DBFactory.java
    • 전달된 값
      • Driver.MARIA
        App.java
    • Driver enum
      • MARIA("maria")
        Driver.java (enum)
        ⬇️
        driver.getProtocol() →"maria"
        DBFactory.java의 creatDB 메서드 내부 if문 조건

    ▶ 4단계: 조건 분기

    if (driver.getProtocol().equals("maria"))
    DBFactory.java의 creatDB 메서드 내부 if문 조건
    ✔ 조건 만족 → MariaDB 객체 생성
    MariaDB mariaDB = new MariaDB(); mariaDB.setUrl("jdbc:mariadb://127.0.0.1:3306"); return mariaDB;
    DBFactory.java의 creatDB 메서드 내부 if문
    ➡️ 여기서 이미 URL 세팅까지 완료됨

    ▶ 5단계: App으로 객체 반환

    App이 받는 건:
    DB db
    ⚠ App은 MariaDB 타입이 아닌 인터페이스 타입 반환 받음

    ▶ 6단계: 실행

    db.execute("select");
    ✔ 실제 호출되는 건 → MariaDB.execute()

    ▶ 콘솔 출력 과정

    • MariaDB 내부
      • System.out.println("query execute : " + path +"/" + sql);
    • 출력 결과
      • queryexecute : jdbc:mariadb://127.0.0.1:3306/select
    Share article
    Contents
    1. 팩토리 패턴 (Factory Pattern)1️⃣ 팩토리 패턴이란?2️⃣ 사용 이유3️⃣ 기본 구조4️⃣ 예시5️⃣ 팩토리 패턴의 장단점6️⃣ 언제 사용?7️⃣ 핵심 목적 🚨2. 실습 (ex09)1️⃣ 실습2️⃣ 실행 흐름 따라가기

    DailyCoding

    RSS·Powered by Inblog