
추상 팩토리는 생성적 디자인 패턴으로, 구체적인 자식 클래스 명시 없이 연관된 객체 그룹을 생성하게 한다. 팩토리에서의 Product가 한 종류에서 여러개로 늘어났다고 생각하면 된다.
- 팩토리 : 한개의 그룹
ex. Transport -> Ship, Truck..- 추상 팩토리 : 여러개의 그룹
ex. Chair->ModernChair, VictorianChair
Sofa->ModernSofa, VictorianSofa

가구가게를 생각해보자. 가구가게 어플리케이션이 제공해야하는 product들은 :

고객이 이미 가지고 있는 버전에 맞는 가구를 제공해야함
ex. 이미 Modern 의자와 소파가 있는데 한개만 Victorian이면 안됨.
새로운 상품이나 연관 상품들을 프로그램에 추가할 때마다 기존의 핵심 코드를 매번 변경하고 싶지 않다.
추상팩토리 패턴을 사용해보자.

위 사진처럼 소파와 커피테이블도 같은 구조를 따를 것이다.

하나의 가구팩토리에는 연관된 가구 그룹을 생성하는 팩토리 메소드들이 있다. 가구팩토리 인터페이스를 구현한 자식 팩토리들은 하나의 버전으로 묶인 가구들을 생성해낸다.
VictorianFurnitureFactory는 Victorian 버전만, ModernFurnitureFactory는 Modern 버전의 가구만 생성한다.
가구를 제공할 때 클라이언트는 팩토리 안에 무슨 팩토리가 있는지, 그 팩토리에서 무슨 버전의 가구를 생성하는지 관심없다. 만약 의자를 생성하고 싶다면, 팩토리의 createChair 메소드를 호출한다. 그 의자가 무슨 버전인지 상관 없이 모두 추상화된 의자 인터페이스를 통해 다룬다. 클라이언트가 보게 되는 것은 오직 의자의 메소드인 sitOn이다.
하지만 추상화된 인터페이스로 비즈니스 로직을 구성한다 하더라도, 결국에 처음에는 조건에 따라 버전별로 팩토리를 생성하는 부분이 있어야 한다. 무엇이 팩토리 객체를 만드는가? 통상적으로, 앱의 초기화 단계에서 추상팩토리를 구현한 자식팩토리들을 생성한다.

Abstract Products : 의자, 소파, 커피테이블 등을 정의
Concrete Products : 각 가구의 여러가지 버전. 의자의 A버전, B버전, 소파의 A버전, B버전 등.
The Abstract Factory : 각 abstract product를 생성하는 메소드들이 존재함
Concrete Factories : 추상 팩토리의 생성 메소드를 구현함. 각 concrete factory는 product의 한 버전에 대응하고 오직 그 버전의 product들만 생성함.
ex VictorianFactory에서는 Victorian 가구만 생성.
비즈니스 로직을 담은 Client Code : Client는 추상 인터페이스들을 통해 모든 concrete factory/product와 상호작용한다.
결국에는 (버전)X(추상 product 개수)만큼의 클래스를 정의해야하는데, 버전이 유한개가 아니거나 특정지어지지 않은 경우에는 어떻게 해야할까?🧐