팩토리 메서드 패턴

이정석·2023년 6월 22일
0

디자인패턴

목록 보기
14/23

팩토리 메서드 패턴이란?

객체의 생성 로직을 서브 클래스에 위임함으로 생성할 클래스의 종류를 결정하는 시점을 뒤로 미루는 패턴이다. 클라이언트가 객체를 직접 생성하는 것이 아니라 팩토리 메서드를 통해 생성된 객체를 받는 방식이다.


문제상황

1. Car 인터페이스와 Sedan, SUV 클래스가 있다 하자.

public interface Car {
    void drive();
}

public class Sedan implements Car {
    @Override
    public void drive() {
        System.out.println("Driving a sedan...");
    }
}

public class SUV implements Car {
    @Override
    public void drive() {
        System.out.println("Driving an SUV...");
    }
}

2. Client가 Sedan과 SUV를 직접 생성하는 코드는 다음과 같다.

public class Client {
    public static void main(String[] args) {
        Car car;
        String carType = "SUV";

        if (carType.equals("Sedan")) {
            car = new Sedan();
        } else if (carType.equals("SUV")) {
            car = new SUV();
        }
        car.drive();
    }
}

위 상황에서 발생하는 문제점은 차의 종류에 따라 if-else문이 많아진다.이다. 이후에 차의 종류를 추가하거나 생성하는 방법이 달라질 때 Client 코드를 바꾸어야 한다.

Car를 생성하는 코드를 별도의 클래스로 분리시켜 이후 객체 생성 방식에 유연하게 만들자


구조

  1. Creator: 팩토리 메서드를 선언한 클래스로 실제 Product를 생성하는 구현 부분은 Creator를 상속받는 클래스에서 구현한다.
  2. ConcreteCreator: Creator를 상속받고 팩토리 메서드를 오버라이드해 ConcretrProduct를 생성하는 클래스이다.
  3. Product: 팩토리 메서드 패턴에서 생성되는 객체들의 인터페이스를 정의한 클래스
  4. ConcreteProduct: Product를 상속받아 인터페이스를 구현하는 클래스로 팩토리 메서드 패턴에서 ConcreteProduct의 인스턴스가 생성된다.

코드(JAVA)

1. Car, Sedan, SUV

public interface Car {
    void drive();
}

public class Sedan implements Car {
    @Override
    public void drive() {
        System.out.println("Driving a sedan...");
    }
}

public class SUV implements Car {
    @Override
    public void drive() {
        System.out.println("Driving an SUV...");
    }
}

Car가 Product이고 Sedan, SUV가 ConcreteProduct에 해당한다.

2. Factories

public abstract class CarFactory {
    public abstract Car createCar();
}

public class SedanFactory extends CarFactory {
    @Override
    public Car createCar() {
        return new Sedan();
    }
}

public class SUVFactory extends CarFactory {
    @Override
    public Car createCar() {
        return new SUV();
    }
}

CarFactory가 Creator에 해당하고 SedanFactory, SUVFactory가 ConcretrFactory에 해당한다. 실제 생성하는 코드 구현부분은 SedanFactory, SUVFactory에 있다.

3. Client

public class Client {
    public static void main(String[] args) {
        CarFactory factory = new SUVFactory();
        Car car = factory.createCar();
        car.drive();
    }
}

Client는 Sedan이나 SUV의 Factory만 알고 있으면 실제 생성은 Factory에서 진행함으로 Sedan, SUV의 생성방식이 바뀌거나 새로운 종류의 차 종류가 추가되어도 받는 영향이 적다.


if문이 필요가 없을까?

팩토리 메서드 패턴을 적용하기 전 발생하는 문제점 중 하나는 많은 if-else문이 발생하는 것이다. 하지만 패턴을 적용하고도 Factory를 교체하는 상황이 발생한다면 결국 if-else문이 필요하게 된다.

결국, 팩토리 메서드 패턴을 적용해도 if-else문이 필요하다. 하지만, 팩토리 메서드 패턴의 목표는 객체 생성 로직을 다른 클래스에서 알 필요가 없도록 하는 것이다.

profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글