추상 팩토리 패턴(Abstract Factory Pattern)

박세건·2024년 5월 22일
0

디자인 패턴

목록 보기
11/17
post-thumbnail

추상 팩토리 메서드란, 연관성이 있는 객체들을 묶어 추상화하고, 팩토리 객체를 통해서 묶은 객체들을 특정한 객체로 구현화 하는 생성 패턴 이다.
핵심은 객체를 타입별로 만들어낼 수 있다는 점이다.

❗하나의 공장 구현체가 2개이상의 객체를 생성할 수 있는 기능을 갖고있다는 것이 특징

구조

  • AbstractFactory : Factory의 기능을 정의하는 인터페이스
  • ContreteFacotry : AbstractFactory를 상속받은 구현체
  • AbstractProduct : 연관성 있는 객체들을 묶어주는 인터페이스
  • ConcreteProduct : AbstractProduct를 상속받은 구현체

예시 코드

  • 제품 객체들을 추상화
// 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
    }
}

추가설명

  • 공장은 A제품과 B제품을 만들어낼 수 있는 기능을 정의 -> AbstractFactory
    • AbstractFactory 구현체인 ConcreteFactory1은 A1과 B1을 생성하도록 구현
    • AbstractFactory 구현체인 ConcreteFactory2은 A2과 B2을 생성하도록 구현
  • A제품을 묶어주는 인터페이스 : AbstractProductA
    • 구현체인 ConcreteProductA1, ConcreteProductA2
  • B제품을 묶어주는 인터페이스 : AbstractProductB
    • 구현체인 ConcreteProductB1, ConcreteProductB2

      숫자 1, 2를 버전이라고 생각하겠음
      추상화된 AbstractFactory에 어떤 구현체가 오는지에 따라서 생성되는 버전이 다름

  • 1번 팩토리 구현체를 사용하고 A를 생성하는 메서드를 생성하면 1버전의 ProductA1가 생성
  • 2번 팩토리 구현체를 사용하고 이전과 같은 메서드를 실행하면 2버전의 ProductA2가 생성
  • B 예시도 동일

Abstract Factory vs Factory Method

공통점

  • 객체의 구체적인 타입을 감추고 객체 생성에 관여
  • 생성 기능과 제품의 기능을 담당하는 구조로 서로 느슨한 구조
  • 클라이언트의
    비슷해보이지만 하지만 명확한 차이를 갖고 있다

차이점

  • 팩토리 메서드 패턴
    • 한 Factory당 하나의 객체 생성 지원
    • 메서드 레벨에 포커스
    • 객체에 초점
  • 추상 팩토리 패턴
    • 한 Factory에서 서로 연관된 여러 종류의 객체 생성을 지원
    • 클래스 레벨에 포커스
    • 객체 집합 군에 초점

추상팩토리 메서드는 구현된 팩토리 객체가 두개이상의 객체를 생성할 수 있다는것이 차이라고 생각

사용 기시

  • 관련 제품이 다양한 제품 군과 같이 작동해야할 때
  • 구체적인 클래스에 의존하고 싶지 않을때
  • 여러 제품군 중 하나를 선택해서 설정해야하고 한번 선택해서 구성한 제품을 다른 것으로 대체할 수 있을 때
  • 제품에 대한 구현의 노출보다는 인터페이스를 노출시키고 싶을 때

장점

  • 생성과 기능의 코드를 분리 -> 결합도 낮춤
  • 제품 군을 쉽게 대체 가능

단점

  • 각 구현체마다 팩토리 객체들을 모두 구현해야 하기에 객체가 늘어날 때마다 클래스가 증가하기 때문에 코드의 복잡도가 증가
  • 추상 팩토리의 코드가 수정되면 모든 팩토리의 수정 필요
  • 새로운 종류의 추가시 구현 로직 변경
profile
멋있는 사람 - 일단 하자

0개의 댓글