생성 패턴의 한 종류인 팩토리 패턴은 객체 생성 과정을 서브클래스로 위임하여, 클라이언트 코드에서 구체적인 클래스를 직접 지정하지 않고도 객체를 생성할 수 있도록 합니다.
1. 팩토리 패턴 개요
객체 생성 로직을 캡슐화하여 코드의 유연성과 재사용성을 높이는 것이 팩토리 패턴의 핵심입니다.
2. 단순 팩토리 (Simple Factory)
팩토리 패턴의 가장 기본적인 형태로, 팩토리 클래스가 단일화되어 특정 조건에 따라 적절한 객체를 생성하여 반환합니다. 클라이언트는 팩토리 클래스에 요청만 하면 됩니다.
package com.example.patterns.factory.simple;
// 객체 생성 대상 인터페이스
interface Product {
void showDetails();
}
// 구체적인 구현체 1
class ConcreteProductA implements Product {
@Override
public void showDetails() {
System.out.println("Details of ConcreteProductA");
}
}
// 구체적인 구현체 2
class ConcreteProductB implements Product {
@Override
public void showDetails() {
System.out.println("Details of ConcreteProductB");
}
}
// 단순 팩토리 클래스
class ProductFactory {
public Product createProduct(String productType) {
if (productType == null || productType.isEmpty()) {
return null;
}
switch (productType.toUpperCase()) {
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new IllegalArgumentException("Unknown product type: " + productType);
}
}
}
// 클라이언트 코드
public class SimpleFactoryDemo {
public static void main(String[] args) {
ProductFactory factory = new ProductFactory();
Product product1 = factory.createProduct("A");
if (product1 != null) {
product1.showDetails();
}
Product product2 = factory.createProduct("B");
if (product2 != null) {
product2.showDetails();
}
}
}
3. 팩토리 메소드 (Factory Method)
객체 생성을 서브클래스에게 위임하는 패턴입니다. 상위 클래스에서는 추상 팩토리 메소드를 정의하고, 실제 객체 생성은 하위 클래스에서 구현합니다.
package com.example.patterns.factory.method;
// 객체 생성 대상 인터페이스
interface Item {
void display();
}
// 구체적인 구현체 1
class Book implements Item {
@Override
public void display() {
System.out.println("This is a Book.");
}
}
// 구체적인 구현체 2
class DVD implements Item {
@Override
public void display() {
System.out.println("This is a DVD.");
}
}
// 추상 팩토리 클래스 (Creator)
abstract class ItemFactory {
public abstract Item createItem(); // 팩토리 메소드
}
// 구체적인 팩토리 클래스 1
class BookFactory extends ItemFactory {
@Override
public Item createItem() {
return new Book();
}
}
// 구체적인 팩토리 클래스 2
class DvdFactory extends ItemFactory {
@Override
public Item createItem() {
return new DVD();
}
}
// 클라이언트 코드
public class FactoryMethodDemo {
public static void main(String[] args) {
ItemFactory bookFactory = new BookFactory();
Item book = bookFactory.createItem();
book.display();
ItemFactory dvdFactory = new DvdFactory();
Item dvd = dvdFactory.createItem();
dvd.display();
}
}
4. 추상 팩토리 (Abstract Factory)
관련되거나 의존적인 객체들의 집합을 생성하기 위한 인터페이스를 제공합니다. 구체적인 클래스를 지정하지 않고도 객체들의 패밀리를 생성할 수 있게 합니다.
package com.example.patterns.factory.abstractfactory;
// --- 제품군 1: GUI 요소 ---
interface Button {
void render();
}
interface Window {
void open();
}
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Windows-style button.");
}
}
class WindowsWindow implements Window {
@Override
public void open() {
System.out.println("Opening a Windows-style window.");
}
}
// --- 제품군 2: GUI 요소 ---
class MacButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Mac-style button.");
}
}
class MacWindow implements Window {
@Override
public void open() {
System.out.println("Opening a Mac-style window.");
}
}
// --- 추상 팩토리 인터페이스 ---
interface GUIFactory {
Button createButton();
Window createWindow();
}
// --- 구체적인 팩토리 1 ---
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Window createWindow() {
return new WindowsWindow();
}
}
// --- 구체적인 팩토리 2 ---
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Window createWindow() {
return new MacWindow();
}
}
// 클라이언트 코드
public class AbstractFactoryDemo {
public static void main(String[] args) {
GUIFactory factory = new WindowsFactory(); // 또는 new MacFactory();
Button button = factory.createButton();
Window window = factory.createWindow();
button.render();
window.open();
}
}