추상 팩토리 패턴은 다양한 구성 요소 별로 '객체의 집합'을 생성해야 할 때 유용하다.
이 패턴을 사용하여 알맞은 객체를 생성할 수 있다.
출처 : 추상 팩토리 패턴 위키
나의 언어로
어떤 클래스(Client)의 멤버 중 알려지지 않은 객체(추상 클래스, Part) 집합을 위한 패턴으로, 알려지지 않은 객체 집합을 채우기 위한 부모 클래스(AbstractFactory)가 존재한다.
부모 클래스를 상속, 구현한 자식 클래스에서 구체적으로 어떤 객체를 생성할지 결정하고 이 자식 클래스를 통해 알려지지 않은 클래스를 채운다.
추상 팩토리 패턴에서 부모 클래스는 어떤 알려지지 않은 객체 집합을 만들 수 있는지 관심이 있다고 생각한다.
출처 : https://refactoring.guru/ko/design-patterns/abstract-factory
이번에도 예제로 확인해 보자.
public class Product {
AbstractTwoPartsFactory abstractTwoPartsFactory;
public Product(AbstractTwoPartsFactory abstractTwoPartsFactory) {
this.abstractTwoPartsFactory = abstractTwoPartsFactory;
}
public void needTwoNewRandomParts() {
PartA partA = abstractTwoPartsFactory.createPartA();
PartB partB = abstractTwoPartsFactory.createPartB();
doSomething(partA, partB);
}
private void doSomething(PartA partA, PartB partB) {}
}
우선 위의 Product는 두개의 Part가 필요하다.
이 Part의 경우 Product가 가지고 있는 것이 아니라 필요할 때마다 생성하여 사용한다.
그렇기에 Product는 PartA와 PartB 객체 집합을 만들 수 있는 AbstractTwoPartsFactory를 가지고 있다.
AbstractTwoPartsFactory는 아래와 같이 가지고 있는 객체 집합의 조합을 다양히 구현할 수 있다.
public interface AbstractTwoPartsFactory {
PartA createPartA();
PartB createPartB();
}
// A1, B1
public class ATwoPartsFactory implements AbstractTwoPartsFactory {
@Override
public PartA createPartA() {
return new PartA1();
}
@Override
public PartB createPartB() {
return new PartB1();
}
}
// A1, B2
public class BTwoPartsFactory implements AbstractTwoPartsFactory {
@Override
public PartA createPartA() {
return new PartA1();
}
@Override
public PartB createPartB() {
return new PartB2();
}
}
이러한 추상 팩토리는 다음과 같은 경우에 적용할 수 있다고 한다.
추상 팩토리는 각 클래스에서 객체들을 생성할 수 있는 인터페이스를 제공한다.
위 인터페이스를 통해 객체들을 생성하는 한 이미 생성된 객체들과 일치하지 않는 잘못된 객체를 생성하지 않을 것이다.
각 클래스는 하나의 책임만 가진다.
클래스가 여러 제품 유형을 상대할 경우, 클래스의 팩토리 메서드들을 독립 실행형 팩토리 클래스 또는 완전한 추상 팩토리 구현으로 추출할 가치가 있을 수 있다.