추상 팩토리 패턴

이정석·2023년 6월 22일
0

디자인패턴

목록 보기
15/23

추상 팩토리 패턴이란?

공통된 특징을 가지고 있는 객체의 패밀리를 생성하는 패턴으로 팩토리의 인터페이스를 정의하고 이후 서브 클래스에서 객체 패밀리를 생성하는 패턴이다.

밑의 추상 팩토리 패턴의 문제상황은 팩토리 메서드 패턴에서 사용한 문제상황과 유사하다. 패턴이름이 비슷하지만 다른 패턴이다.


문제상황

1. Car를 만들기 위해서 Engine와 Wheel이 필요하다.

interface Engine {
    void move();
}

interface Wheel {
    void rotate();
}

2. Sedan을 만들기 위해서는 SedanEngine과 SedanWheel이 필요하다.

class SedanEngine implements Engine {
    public void move() {
        System.out.println("Moving Sedan Engine...");
    }
}

class SedanWheel implements Wheel {
    public void rotate() {
        System.out.println("Rotating Sedan Wheel...");
    }
}

3. SUV를 만들기 위해서는 SUVEngine과 SUVWheel이 필요하다.

class SUVEngine implements Engine {
    public void move() {
        System.out.println("Moving SUV Engine...");
    }
}

class SUVWheel implements Wheel {
    public void rotate() {
        System.out.println("Rotating SUV Wheel...");
    }
}

4. Sedan이나 SUV의 부품(Engine, Wheel)을 만드는 Client 코드는 다음과 같다.

public class Client {
    public static void main(String[] args) {
        Engine engine;
        Wheel wheel;

        String carType = "SUV";

        if (carType.equals("Sedan")) {
            engine = new SedanEngine();
            wheel = new SedanWheel();
        } else {
            engine = new SUVEngine();
            wheel = new SUVWheel();
        }

        engine.move();
        wheel.rotate();
    }
}

위 상황에서 Client는 각 Car에 해당하는 부품들을 직접 생성한다. 이러한 상황은 다음과 같은 문제가 발생한다.

  • Sedan, SUV말고 Truck이라는 차 종류가 추가 된다면?
  • Engine, Wheel말고 Door라는 부품이 추가 된다면?

위 두개의 상황 모두 Client 코드를 수정해야 하며 많아진다면 코드의 가독성이 크게 떨어진다.

부품을 생성하는 하나의 Factory를 정의하고 어떤 제품군을 생성할지는 서브클래스에서 결정하자


구조

  1. AbstractFactory: 팩토리 클래스의 공통 인터페이스를 정의한 클래스로 각각의 Product를 생성하는 기능을 추상 메소드로 정의하고 서브 클래스에서 구현한다.
  2. ConcreteFactory: AbstractFactory 클래스를 상속받아 구현한 클래스로 실제 ConcreteProduct를 생성하는 메소드를 오버라이딩함으로 구현한다.
  3. AbstractProduct: Product 객체의 공통 인터페이스를 정의한 클래스
  4. ConcreteProduct: AbstractProduct를 상속받아 구현한 클래스로 구체적인 부품에 해당한다.

코드(JAVA)

1. Engine, Wheel, CarFactory

interface Engine {
    void move();
}

interface Wheel {
    void rotate();
}

interface CarFactory {
    Engine createEngine();
    Wheel createWheel();
}

2. Sedan, SUV

class SedanEngine implements Engine {
    public void move() {
        System.out.println("Moving Sedan Engine...");
    }
}

class SedanWheel implements Wheel {
    public void rotate() {
        System.out.println("Rotating Sedan Wheel...");
    }
}

class SUVEngine implements Engine {
    public void move() {
        System.out.println("Moving SUV Engine...");
    }
}

class SUVWheel implements Wheel {
    public void rotate() {
        System.out.println("Rotating SUV Wheel...");
    }
}

구조의 ConcreteProduct에 해당한다.

3. SedanCarFactory, SUVCarFactory

class SedanCarFactory implements CarFactory {
    public Engine createEngine() {
        return new SedanEngine();
    }

    public Wheel createWheel() {
        return new SedanWheel();
    }
}

class SUVCarFactory implements CarFactory {
    public Engine createEngine() {
        return new SUVEngine();
    }

    public Wheel createWheel() {
        return new SUVWheel();
    }
}

각 Factory는 제품군에 맞는 ConcreteProduct를 생성한다.

3. Client

public class Client {
    public static void main(String[] args) {
        CarFactory carFactory;

        String carType = "SUV";

        if (carType.equals("Sedan")) {
            carFactory = new SedanCarFactory();
        } else {
            carFactory = new SUVCarFactory();
        }

        Engine engine = carFactory.createEngine();
        Wheel wheel = carFactory.createWheel();

        engine.move();
        wheel.rotate();
    }
}

패턴이 적용된 상황에서 앞서 언급한 문제상황에 대해서 살펴보면 다음과 같다.

  • Sedan, SUV말고 Truck이라는 차 종류가 추가 된다면?

    TruckCarFactory, TruckEngine, TruckWheel을 추가하면 된다.

  • Engine, Wheel말고 Door라는 부품이 추가 된다면?

    interface Door와 이를 상속받는 SedanDoor와 SUVDoor를 추가하면 된다.

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

0개의 댓글