[GOF] 추상 팩토리 패턴
2024. 4. 2. 15:20ㆍ디자인패턴
1. Abstrract Factory Pattern
- 연관성이 있는 객체 군이 여러개 있을 경우 이들을 묶어서 추상화하고, 팩토리 객체에서 집합으로 묶은 객체 군을 구현화하는 패턴
- 특정 객체를 사용할 때 팩토리 클래스만을 참조하여 특정 객체에 대한 구현부를 감추어 역할과 구현을 분리
- AbstractFactory : 최상위 공장 클래스. 여러개의 제품들을 생성하는 여러 메소드들을 추상화한다.
- ConcreteFactory : 서브 공장 클래스들은 타입에 맞는 제품 객체를 반환하도록 메소드들을 재정의 한다.
- AbstractProduct : 각 타입의 제품들을 추상화한 인터페이스
- ConcreteProduct (ProductA ~ ProductB) : 각 타입의 제품 구현체들. 이들은 팩토리 객체부터 생성
- Client : Client는 추상화된 인터페이스만을 이용하여 제품을 받기때문에, 구체적인 제품, 공장에 대해서는 모른다.
팩토리 메서드 패턴 | 추상 팩토리 패턴 | |
공통점 | 객체 생성 과정을 추상화한 인터페이스를 제공 객체 생성을 캡슐화함으로써 구체적인 타입을 감추고 느슨한 결합 구조를 표방 |
|
차이점 | 구체적인 객체 생성과정을 하위 또는 구체적인클래스로 옮기는 것이 목적 | 관련 있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들 수 있게 해주는 것이 목적 |
한 Factory당 한 종류의 객체 생성 지원 | 한 Factory에서 서로 연관된 여러 종류의 객체 생성을 지원 | |
메소드 레벨에서 포커스를 맞춤으로써, 클라이언트의 ConcreteProduct 인스턴스의 생성 및 구성에 대한 의존을 감소 | 클래스(Factory) 레벨에서 포커스를 맞춤으로써, 클라이언트의 ConcreteProduct 인스턴스 군의 생성 및 구성에 대한 의존을 감소 |
2. 패턴 흐름
// 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
}
}
코드를 보면 똑같은 createProductA() 메서드를 호출하지만 어떤 팩토리 객체이냐에 따라 반환되는 제품군이 다르게 된다.
3. 사용 시기와 장/단점
- 관련 제품의 다양한 제품 군과 함께 작동해야 할때, 해당 제품의 구체적인 클래스에 의존하고 싶지 않은 경우
- 여러 제품군 중 하나를 선택해서 시스템을 설정해야하고, 한번 구성한 제품을 다른것으로 대체할 수도 있을 때
- 제품에 대한 클래스 라이브러리를 제공하고, 그들의 구현이 아닌 인터페이스를 노출시키고 싶을 때
'디자인패턴' 카테고리의 다른 글
[GOF] 템플릿 메소드 패턴 (0) | 2024.03.19 |
---|---|
[GOF] 상태(State) 패턴 (0) | 2024.03.18 |
[GOF] 전략(Strategy) 패턴 (0) | 2024.03.17 |
[GOF] 싱글톤(Singleton) 패턴 (1) | 2024.03.16 |