[GOF] 추상 팩토리 패턴

2024. 4. 2. 15:20디자인패턴

1.  Abstrract Factory Pattern

  • 연관성이 있는 객체 군이 여러개 있을 경우 이들을 묶어서 추상화하고, 팩토리 객체에서 집합으로 묶은 객체 군을 구현화하는 패턴
  • 특정 객체를 사용할 때 팩토리 클래스만을 참조하여 특정 객체에 대한 구현부를 감추어 역할과 구현을 분리

 

  • AbstractFactory : 최상위 공장 클래스. 여러개의 제품들을 생성하는 여러 메소드들을 추상화한다.
  • ConcreteFactory : 서브 공장 클래스들은 타입에 맞는 제품 객체를 반환하도록 메소드들을 재정의 한다.
  • AbstractProduct : 각 타입의 제품들을 추상화한 인터페이스
  • ConcreteProduct (ProductA ~ ProductB) : 각 타입의 제품 구현체들. 이들은 팩토리 객체부터 생성
  • Client : Client는 추상화된 인터페이스만을 이용하여 제품을 받기때문에, 구체적인 제품, 공장에 대해서는 모른다.
  팩토리 메서드 패턴 추상 팩토리 패턴
공통점 객체 생성 과정을 추상화한 인터페이스를 제공
객체 생성을 캡슐화함으로써 구체적인 타입을 감추고 느슨한 결합 구조를 표방
차이점 구체적인 객체 생성과정을 하위 또는 구체적인클래스로 옮기는 것이 목적 관련 있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들 수 있게 해주는 것이 목적
한 Factory당 한 종류의 객체 생성 지원 한 Factory에서 서로 연관된 여러 종류의 객체 생성을 지원
메소드 레벨에서 포커스를 맞춤으로써, 클라이언트의 ConcreteProduct 인스턴스의 생성 및 구성에 대한 의존을 감소 클래스(Factory) 레벨에서 포커스를 맞춤으로써, 클라이언트의 ConcreteProduct 인스턴스 군의 생성 및 구성에 대한 의존을 감소

 

2. 패턴 흐름

// Product A 제품군
interface AbstractProductA {
}

// Product A - 1
class ConcreteProductA1 implements AbstractProductA {
}

// Product A - 2
class ConcreteProductA2 implements AbstractProductA {
}
// Product B 제품군
interface AbstractProductB {
}

// Product B - 1
class ConcreteProductB1 implements AbstractProductB {
}

// Product B - 2
class ConcreteProductB2 implements AbstractProductB {
}

 

공장 클래스

interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

// Product A1와 B1 제품군을 생산하는 공장군 1 
class ConcreteFactory1 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// Product A2와 B2 제품군을 생산하는 공장군 2
class ConcreteFactory2 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }
    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

클라이언트

class Client {
    public static void main(String[] args) {
    	AbstractFactory factory = null;
        
        // 1. 공장군 1을 가동시킨다.
        factory = new ConcreteFactory1();

        // 2. 공장군 1을 통해 제품군 A1를 생성하도록 한다 (클라이언트는 구체적인 구현은 모르고 인터페이스에 의존한다)
        AbstractProductA product_A1 = factory.createProductA();
        System.out.println(product_A1.getClass().getName()); // ConcreteProductA1

        // 3. 공장군 2를 가동시킨다.
        factory = new ConcreteFactory2();

        // 4. 공장군 2를 통해 제품군 A2를 생성하도록 한다 (클라이언트는 구체적인 구현은 모르고 인터페이스에 의존한다)
        AbstractProductA product_A2 = factory.createProductA();
        System.out.println(product_A2.getClass().getName()); // ConcreteProductA2
    }
}

코드를 보면 똑같은 createProductA() 메서드를 호출하지만 어떤 팩토리 객체이냐에 따라 반환되는 제품군이 다르게 된다.

 

3. 사용 시기와 장/단점

  • 관련 제품의 다양한 제품 군과 함께 작동해야 할때, 해당 제품의 구체적인 클래스에 의존하고 싶지 않은 경우
  • 여러 제품군 중 하나를 선택해서 시스템을 설정해야하고, 한번 구성한 제품을 다른것으로 대체할 수도 있을 때
  • 제품에 대한 클래스 라이브러리를 제공하고, 그들의 구현이 아닌 인터페이스를 노출시키고 싶을 때

'디자인패턴' 카테고리의 다른 글

[GOF] 템플릿 메소드 패턴  (0) 2024.03.19
[GOF] 상태(State) 패턴  (0) 2024.03.18
[GOF] 전략(Strategy) 패턴  (0) 2024.03.17
[GOF] 싱글톤(Singleton) 패턴  (1) 2024.03.16