팩터리 메서드 패턴
기본 클래스에 팩터리 메서드를 정의하고 어떤 제품을 만들지 하위 클래스가 결정하도록 합니다.
팩터리 메서드 패턴은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
팩토리 메서드의 의도
팩토리 메서드는 객체를 생성하기 위한 인터페이스를 정의하지만, 어떤 클래스를 인스턴스화할지는 하위 클래스가 결정하도록 합니다. 이를 통해 생성 로직과 클라이언트 코드를 분리합니다.
팩토리 메서드가 없을 때의 문제
팩토리가 없으면 클라이언트 코드 곳곳에 new ConcreteClass() 호출이 흩어집니다. 새로운 변형을 추가하려면 모든 호출 위치를 변경해야 하므로, 개방-폐쇄 원칙을 위반하게 됩니다.
// Client knows too much:
Shape shape;
if (type.equals("circle")) shape = new Circle(r);
else if (type.equals("rect")) shape = new Rectangle(w, h);
// Every new shape requires editing this code.생성자 추상 클래스
createProduct() 팩토리 메서드를 포함하는 추상 생성자 클래스를 정의합니다. 하위 클래스는 이 메서드를 재정의하여 특정 제품 유형을 반환합니다.
public abstract class Dialog {
public void render() {
Button btn = createButton(); // factory method
btn.onClick();
}
protected abstract Button createButton();
}구체 생성자
각 하위 클래스는 팩토리 메서드를 재정의하여 적절한 제품을 반환하며, 기본 클래스에 정의된 주변 알고리즘은 변경하지 않습니다.
public class WindowsDialog extends Dialog {
@Override
protected Button createButton() { return new WindowsButton(); }
}
public class WebDialog extends Dialog {
@Override
protected Button createButton() { return new HtmlButton(); }
}제품 인터페이스
모든 구체 제품은 공통 인터페이스를 구현하므로, 생성자는 제품을 구체적인 유형과 무관하게 다룰 수 있습니다.
public interface Button {
void onClick();
void render();
}
public class WindowsButton implements Button {
public void onClick() { System.out.println("Windows click"); }
public void render() { System.out.println("Render Windows button"); }
}정적 팩토리 메서드와 팩토리 메서드 패턴
정적 팩토리 메서드(예: LocalDate.of())는 명명 규칙일 뿐 GoF 패턴이 아닙니다. GoF 패턴은 상속을 사용하고, 정적 팩토리는 하나의 클래스에서 정적 메서드를 사용합니다.
// Static factory (NOT the GoF pattern)
LocalDate d = LocalDate.of(2024, 6, 15);
// GoF Factory Method uses a class hierarchy매개변수를 사용하는 팩토리 메서드
팩토리 메서드에 매개변수를 전달하여 제품마다 하위 클래스를 만들지 않고 여러 제품 중 하나를 선택합니다.
public class ShapeFactory {
public static Shape create(String type, double... dims) {
return switch (type) {
case "circle" -> new Circle(dims[0]);
case "rectangle" -> new Rectangle(dims[0], dims[1]);
default -> throw new IllegalArgumentException("Unknown: " + type);
};
}
}제네릭을 사용하는 팩토리 메서드
제네릭을 사용하면 팩토리 메서드를 여러 제품군에서 형식 안전하고 재사용 가능하게 만들 수 있습니다.
public abstract class Repository<T, ID> {
public abstract T findById(ID id);
protected abstract T createEmpty(); // factory method
}Map에 팩토리 등록하기
레지스트리 기반 팩토리는 형식 문자열을 Supplier 람다에 매핑하여 저장합니다. 이를 통해 여러 if-else 조건문을 피하고 등록을 동적으로 처리할 수 있습니다.
Map<String, Supplier<Notification>> registry = new HashMap<>();
registry.put("email", EmailNotification::new);
registry.put("sms", SmsNotification::new);
Notification n = registry.getOrDefault(type, DefaultNotification::new).get();팩토리 메서드와 추상 팩토리
팩토리 메서드는 상속을 통해 하나의 제품 유형을 생성합니다. 추상 팩토리는 구성을 통해 서로 관련된 제품군을 생성합니다. 하나의 제품만 달라질 때는 팩토리 메서드를, 전체 제품군이 함께 달라질 때는 추상 팩토리를 사용합니다.
실제 사례: 로거 팩토리
SLF4J의 LoggerFactory.getLogger(Class)는 호출자가 어떤 구현인지 알 필요 없이 올바른 로거 구현(Logback, Log4j, JUL)을 반환하는 정적 팩토리입니다.
Logger log = LoggerFactory.getLogger(MyService.class);
log.info("Service started");빠른 확인
팩토리 메서드 패턴의 핵심 특징은 무엇입니까?
정리
팩토리 메서드는 인스턴스화 결정을 재정의 가능한 하위 클래스 메서드에 맡겨 객체 생성과 클라이언트를 분리합니다. 클래스가 생성해야 할 객체의 종류를 미리 예상할 수 없을 때 사용합니다.
자주 묻는 질문
“팩터리 메서드 패턴” 강의는 무료인가요?
네 — “팩터리 메서드 패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“팩터리 메서드 패턴”에서 뭘 배우나요?
기본 클래스에 팩터리 메서드를 정의하고 어떤 제품을 만들지 하위 클래스가 결정하도록 합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Java Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“팩터리 메서드 패턴” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.