추상 팩토리 패턴은 다양한 구성 요소 별로 '객체의 집합'을 생성해야 할 때 유용하다. 이 패턴을 사용하여 상황에 알맞은 객체를 생성할 수 있다. - wiki
추상 팩토리는 관련 객체들의 구상 클래스들을 지정하지 않고도 관련 객체들의 모음을 생성할 수 있도록 하는 생성패턴입니다. - guru
객체 생성을 캡슐화함으로써 구체적인 타입을 감추고 느슨한 결합 구조를 만든다.
팩토리 메서드 패턴 | 추상 팩토리 패턴 |
---|---|
조건에 따른 객체 생성을 팩토리 클래스로 위임하여, 팩토리 클래스에서 객체를 생성하는 패턴 | 서로 관련있는 객체들을 통째로 묶어서 팩토리 클래스로 만들고, 이들 팩토리를 조건에 따라 생성하도록 다시 팩토리를 만들어서 객체를 생성하는 패턴 |
한 Factory에서 서로 연관된 여러 종류의 객체 생성을 지원. (제품군 생성 지원) | 한 Factory당 한 종류의 객체 생성 지원 |
인자에 따라 객체들을 생성하는 Factory의 종류가 결정. (다수의 Factory 존재) | 인자에 따라 생성되는 객체의 종류가 결정 |
엘레베이터를 만들기 위해 문과 모터를 만들어주는 공장이 존재한다고 가정하겠습니다.
그리고 엘레베이터 제조사는 LG와 삼성이 있다고 가정하겠습니다.
즉, LG공장에서는 LG 브랜드의 문과 모터를 만들고, 삼성 공장에서는 삼성 브랜드의 문과 모터를 만듭니다.
//LG 브랜드의 문 구현체
public class LGDoor implements Door {
public LGDoor() {
System.out.println("LG Door 생성");
}
}
//LG 브랜드의 모터 구현체
public class LGMotor implements Motor {
public LGMotor() {
System.out.println("LG Motor 생성");
}
}
//문 브랜드를 골라주는 Factory
public class DoorFactory {
public static Door createDoor(Brand brand) {
Door door = null;
switch (brand) {
case LG -> {
door = new LGDoor();
break;
}
case SamSung -> {
door = new SamSumgDoor();
break;
}
}
return door;
}
}
//모터 브랜드를 골라주는 Factory
public class MotorFactory {
public static Motor createMotor(Brand brand) {
Motor motor = null;
switch (brand) {
case LG -> {
motor = new LGMotor();
break;
}
case SamSung -> {
motor = new SamSumgMotor();
break;
}
}
return motor;
}
}
public class Client {
public static void main(String[] args) {
Door lgDoor = DoorFactory.createDoor(Brand.LG); // 팩토리 메서드 호출
Motor lgMotor = MotorFactory.createMotor(Brand.LG); // 팩토리 메서드 호출
//부품을 합쳐 로직 실행
}
}
서로 관련있는 객체들을 통째로 묶어서 팩토리 클래스로 만들고, 이들 팩토리를 조건에 따라 생성하도록 다시 팩토리를 만들어서 객체를 생성하는 패턴
즉, 별도의 Factory 클래스로 만드는 것이 아닌 관련있는 객체들을 묶어서 생성하는 Factory 클래스를 이용하는 것을 의미합니다.
부품(이전 팩토리 메서드와 동일)
//LG 브랜드의 문 구현체
public class LGDoor implements Door {
public LGDoor() {
System.out.println("LG Door 생성");
}
}
//LG 브랜드의 모터 구현체
public class LGMotor implements Motor {
public LGMotor() {
System.out.println("LG Motor 생성");
}
}
엘레베이터를 만들어주는 LGElevatorFactory와 SamsungElevatorFactory 클래스를 정의하고, 이들을 캡슐화하는 ElevatorFactory 인터페이스를 정의합니다.
엘레베이터 팩토리에서 각각 브랜드에 맞는 문과 모터를 생성합니다.
//LG 브랜드 엘레베이터를 생성해주는 팩토리 클래스
public class LGElevatorFactory implements ElevatorFactory{
@Override
public Door createDoor() {
return new LGDoor();
}
@Override
public Motor createMotor() {
return new LGMotor();
}
}
//캡슐화
public interface ElevatorFactory {
Door createDoor();
Motor createMotor();
}
다음으로는 FactoryOfElevatorFactory 클래스를 확인하겠습니다.
이 클래스는 팩토리 패턴에서의 팩토리와 하는 일이 동일합니다.
브랜드에 따라 어느 브랜드의 엘레베이터를 만들어주지를 결정합니다.
부품이 아니라 엘레베이터를 생성한다는 것이 핵심!!
public class FactoryOfElevatorFactory {
public void createElevator(Brand brand) {
ElevatorFactory elevatorFactory = null;
switch (brand) {
case LG -> {
elevatorFactory = new LGElevatorFactory();
break;
}
case SamSung -> {
elevatorFactory = new SamSungElevatorFactory();
break;
}
}
elevatorFactory.createDoor();
elevatorFactory.createMotor();
}
}
``` 엘레베이터를 사용할 Client입니다.
> 마지막으로
```java
public class AbstractFactoryClient {
public static void main(String[] args) {
FactoryOfElevatorFactory factoryOfElevatorFactory = new FactoryOfElevatorFactory();
factoryOfElevatorFactory.createElevator(Brand.LG);
}
}
추상 팩토리 패턴은 팩토리 메서드 패턴을 한층 더 캡슐화한 방식이라고 생각합니다.