디자인패턴
[Java][디자인 패턴] 4. 추상 팩토리 패턴 (Abstract Factory Pattern)
추상 팩토리 패턴은 팩토리 메서드 패턴을 확장한 패턴이다.
추상 팩토리 패턴이란?
- 추상 팩토리 패턴은 팩토리 메서드 패턴을 확장한 패턴이다.
- 이 말은 즉슨, 팩토리 메서드를 여러 개를 만들고 그룹핑해서 하나로 관리할 수 있도록 만든 게 추상 팩토리 패턴이라고 볼 수 있다.
팩토리 패턴 vs 팩토리 메서드 패턴 vs 추상 팩토리 패턴
- 팩토리 패턴 vs 팩토리 메서드 패턴
추상화의 여부로 알 수 있다. 팩토리는 바로 클래스들의 생성을 한 곳에 모아서 new로 관리해주고, 팩토리 메서드는 추상화한 상위 클래스 아래에 하위 클래스를 두고, 실제 객체의 생성은 하위 클래스에게 위임한다. (선언과 구현을 분리한다.) - 팩토리 메서드 패턴 vs 추상 팩토리 패턴
추상화된 그룹을 형성하고 관리한다는 점에서 차이가 있다. 추상 팩토리는 추상화한 팩토리들을 그룹 지어 관리한다. 즉, 추상 팩토리는 여러 개의 팩토리 메서드를 그룹으로 묶어 놓은 것과 같다. 추상 팩토리는 다양한 객체 생성 과정에서 그룹화가 필요할 경우 유용하다. - 팩토리 패턴) https://hirlawldo.tistory.com/158
- 팩토리 메서드 패턴) https://hirlawldo.tistory.com/163
추상 팩토리 패턴 구조
예시 코드는 쉽게 배워 바로 써먹는 디자인 패턴에서 나온 PHP 예시 코드를 Java 코드로 바꾸고 약간 변형한 코드이다.
(좋은 예시가 떠오르지 않아서 책에 있는 예시를 참고했다.)
추상 팩토리 패턴은 위와 같이 해결해야 하는 목적에 따라 그룹을 만든다. 예를 들어 위와 같이 하나의 차를 만들기 위한 목적을 달성하기 위해 Car를 구성하는 Tire, Door, Engine 등의 그룹이 있다고 가정해보자. 그럴 때 각각의 그룹을 달성하는 방법도 여러 가지가 있을 수 있다. 예를 들면 현대차가 해외에 팔렸을 때에는 Door, Tire가 동작하는 방식이 다를 수 있고, 각 공장별로 다른 전체적인 구성은 같더라도 다른 동작을 수행할 수 있다. 혹은 2차 벤더, 3차 벤더가 각각 다른 곳이 수주할 수도 있다. 이럴 경우 Tire와 Door 등의 각각의 그룹에 대한 목적을 달성하고, 그 추상 그룹들을 이용해 완성된 차를 만드는 CarFactory가 TireProduct, DoorProduct 추상 클래스를 이용하여 완성품 차를 만들 수 있다.
팩토리 패턴 코드
1. DoorProduct, TireProduct 추상 클래스
public abstract class DoorProduct {
public abstract String makeAssemble();
}
public abstract class TireProduct {
public abstract String makeAssemble();
}
2.DoorProduct, TireProduct를 실제로 구현하는 클래스들
- 미국산, 한국산 Door와 Tire를 실제로 만드는 팩토리 클래스들
- 이전에 팩토리 메서드에서 하나의 추상 팩토리가 있고, 그 아래 하위 클래스들이 있는데 DoorProduct 하나가 팩토리 메서드라고 보면 된다.
public class KoreaDoorProduct extends DoorProduct {
@Override
public String makeAssemble() {
return "문이 열립니다.";
}
}
public class KoreaTireProduct extends TireProduct {
public KoreaTireProduct() {
}
@Override
public String makeAssemble() {
return "국산 타이어";
}
}
public class StateDoorProduct extends DoorProduct {
@Override
public String makeAssemble() {
return "Door is open";
}
}
public class StateTireProduct extends TireProduct {
public StateTireProduct() {
}
@Override
public String makeAssemble() {
return "미국산 타이어";
}
}
3. CarFactory로 Korea, State 차를 조립해서 생성하는 CarFactory 추상 클래스
public abstract class CarFactory {
public abstract TireProduct createTire();
public abstract DoorProduct createDoor();
}
public class KoreaCarFactory extends CarFactory{
public KoreaCarFactory() {
}
@Override
public TireProduct createTire() {
return new KoreaTireProduct();
}
@Override
public DoorProduct createDoor() {
return new KoreaDoorProduct();
}
}
public class StateCarFactory extends CarFactory {
@Override
public TireProduct createTire() {
return new StateTireProduct();
}
@Override
public DoorProduct createDoor() {
return new StateDoorProduct();
}
}
4. CarFactory로 차가 잘 만들어지나 확인하는 테스트 코드
class CarFactoryTest {
@Test
@DisplayName("한국산 차 만들기")
void makeKoreaCar(){
// given
CarFactory carFactory = new KoreaCarFactory();
TireProduct tireProduct = carFactory.createTire();
DoorProduct doorProduct = carFactory.createDoor();
// when
String tire = tireProduct.makeAssemble();
String door = doorProduct.makeAssemble();
// then
assertEquals("국산 타이어", tire);
assertEquals("문이 열립니다.", door);
}
@Test
@DisplayName("미국산 차 만들기")
void makeStateCar(){
// given
CarFactory carFactory = new StateCarFactory();
TireProduct tireProduct = carFactory.createTire();
DoorProduct doorProduct = carFactory.createDoor();
// when
String tire = tireProduct.makeAssemble();
String door = doorProduct.makeAssemble();
// then
assertEquals("미국산 타이어", tire);
assertEquals("Door is open", door);
}
}
만약 추상 팩토리에 새로운 부품을 추가한다면?
만약 추상 팩토리에 새로운 부품인 Engine을 추가해야 한다면 어떻게 될까?
이 경우, 추상 클래스 그룹으로 분리된 모든 클래스에 Engine 부품 관련 코드를 삽입해야 한다. 이와 같이 추상 팩토리 패턴은 그룹을 나누는 것은 쉽지만 서브 생성 객체를 추가하는 것은 어렵다. 즉 생성된 그룹을 통해 전체를 쉽게 변경하거나 관리하기 쉽다는 장점은 있지만 서브 생성 객체를 추가해야 한다면 OCP를 위반하게 되기 때문에 확장성 부분에서는 좋지 않을 수 있다는 점에 주의해야 한다.
Github 코드
참고 자료
1.쉽게 바로 써먹는 디자인 패턴 책
http://www.yes24.com/Product/Goods/93173296
'개발 > 디자인패턴' 카테고리의 다른 글
[Java][디자인 패턴] 6. 프로토타입 패턴 (Prototype Pattern) (0) | 2022.03.05 |
---|---|
[Java][디자인 패턴] 5. 빌더 패턴 (Builder Pattern) (0) | 2022.03.04 |
[Java][디자인 패턴] 3. 팩토리 메서드 패턴 (Factory Method Pattern) (0) | 2022.03.02 |
[Java][디자인 패턴] 2. 싱글턴 패턴 (Singleton Pattern) (0) | 2022.03.01 |
[Java][디자인 패턴] 1. 팩토리 패턴 (Factory Pattern) (0) | 2022.02.28 |