추상 팩토리 디자인 패턴(Abstract Factory Design Pattern)은 객체 생성에 관련된 일련의 인터페이스를 제공하여, 관련 객체들의 생성을 캡슐화하고 클라이언트 코드가 구체적인 클래스의 인스턴스를 직접 생성하는 것을 피하도록 하는 디자인 패턴 중 하나입니다.
이 패턴은 주로 "팩토리"라 불리는 인터페이스를 통해 다양한 종류의 관련 제품을 생성하는 데 사용됩니다. 각각의 팩토리는 특정 제품군에 대해 추상화된 인터페이스를 제공하며, 클라이언트 코드는 이러한 인터페이스를 통해 제품을 생성합니다. 이는 객체 생성 로직을 클라이언트 코드로부터 분리함으로써 시스템의 유연성을 향상하고, 객체 간의 결합도를 낮추어 변경과 확장에 용이하게 만듭니다.
추상 팩토리 패턴 구조(Abstract Factory Pattern Structure)
- 제품 인터페이스(Abstract Product): 팩토리에서 생성되는 객체의 공통 인터페이스를 정의.
- 팩토리 인터페이스(Abstract Factory): 제품의 생성을 담당하는 메서드를 정의한 인터페이스.
- 구체적인 제품(Concrete Product): 제품 인터페이스를 실제로 구현한 클래스.
- 구체적인 팩토리(Concrete Factory): 팩토리 인터페이스를 구현하여 실제 제품을 생성하는 클래스.
클라이언트 코드는 원하는 팩토리를 선택하고, 해당 팩토리를 사용하여 제품을 생성합니다. 이로써 클라이언트 코드는 구체적인 클래스에 의존하지 않으면서도 다양한 제품을 생성할 수 있게 됩니다.
추상 팩토리 패턴은 객체 지향 디자인의 원칙 중 하나인 "의존성 역전 원칙(Dependency Inversion Principle)"을 따르며, 시스템의 확장성과 유지보수성을 높여줍니다. 이 패턴은 특히 GUI 라이브러리, 데이터베이스 연동, 통신 프로토콜 등과 같이 객체 생성이 복잡하고 다양한 상황에서 유용하게 적용됩니다.
추상 팩토리 패턴 흐름(Abstract Factory pattern Flow)
추상 팩토리 패턴은 객체 생성을 캡슐화하고, 클라이언트 코드가 구체적인 클래스를 직접 생성하지 않도록 하는 디자인 패턴이며, 패턴의 동작 흐름을 살펴보면 다음과 같습니다.
1. 제품 인터페이스 정의(Abstract Product Interface definition)
생성될 제품의 공통 인터페이스를 정의합니다. 이 인터페이스는 생성될 모든 제품 클래스가 구현해야 하는 메서드들로 이루어져 있습니다.
interface AbstractProductA {
void method();
}
interface AbstractProductB {
void method();
}
2. 팩토리 인터페이스 정의(Abstract Factory Interface definition)
제품을 생성하는 추상 팩토리를 정의합니다. 이 팩토리 인터페이스는 각 제품에 대한 생성 메서드를 제공합니다. 이렇게 하면 클라이언트 코드는 어떤 제품을 사용할지에 대한 결정을 내리지 않고, 단지 추상 팩토리의 인터페이스를 통해 제품을 생성할 수 있습니다.
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
3. 구체적인 제품 클래스 구현(Concreate Product Class Implementation)
팩토리가 생성할 제품의 구체적인 클래스들을 정의합니다. 각 제품 클래스는 제품 인터페이스를 구현하며, 실제 동작을 구현합니다.
class ConcreateProductA implements AbstractProductA {
@Override
public void method() {
...
}
}
class ConcreateProductB implements AbstractProductB {
@Override
public void method() {
...
}
}
4. 구체적인 팩토리 클래스 구현(Concreate Factory Class Implementation)
팩토리 인터페이스를 구현하여 각 제품에 대한 실제 생성 로직을 제공합니다. 이로써 클라이언트 코드는 구체적인 팩토리의 인터페이스를 통해 제품을 생성할 수 있습니다.
class ConcreateFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreateProductA();
}
@Override
public AbstractProductB createProductB() {
return new ConcreateProductB();
}
}
class ConcreateFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreateProductA();
}
@Override
public AbstractProductB createProductB() {
return new ConcreateProductB();
}
}
5. 클라이언트 코드 작성(Client Code)
클라이언트 코드에서는 사용할 팩토리를 선택하고, 해당 팩토리의 메서드를 호출하여 제품을 생성합니다. 이때 클라이언트는 추상 팩토리의 인터페이스만을 참조하며, 어떤 구체적인 제품이 생성되는지에 대한 지식이 없습니다.
public class Client {
private final AbstractFactory factory;
public Client(AbstractFactory factory) {
this.factory = factory;
}
public void orderProducts() {
AbstractProduct productA = factory.createProductA();
AbstractProduct productB = factory.createProductB();
productA.method();
productB.method();
}
publict static void main(String[] args) {
Client comdolidol_i = new Client(new ConcreateFactory1());
comdolidol_i.orderProducts();
}
}
추상 팩토리 패턴 특징(Abstract Factory Patterns Characteristic)
- 객체 생성의 추상화: 추상 팩토리 패턴은 객체 생성을 추상화하여 클라이언트가 구체적인 클래스를 직접 생성하는 것을 피하도록 합니다. 이를 통해 시스템의 유연성이 증가하고 객체 간의 결합도가 낮아집니다.
- 관련된 객체군 생성: 팩토리 인터페이스는 일반적으로 관련된 객체군을 생성하는 역할을 합니다. 예를 들어 GUI 컴포넌트, 데이터 베이스 연결 등과 같이 여러 종류의 객체가 함께 사용되는 경우 유용합니다.
- 클라이언트 코드의 단순화: 클라이언트 코드에서는 어떤 구체적인 클래스가 생성되는지 알 필요가 없습니다. 팩토리의 인터페이스를 통해 제품을 생성하고 사용함으로써 코드가 단순화됩니다.
장점
- 객체 간의 결합도 감소: 클라이언트 코드는 구체적인 클래스에 의존하지 않고 팩토리의 인터페이스를 통해 제품을 생성하기 때문에 객체 간의 결합도가 감소합니다.
- 유연성과 확장성 향상: 새로운 제품이나 팩토리를 추가하거나 기존의 것을 변경하기 쉽습니다. 시스템의 유연성과 확장성이 향상됩니다.
- 코드 재사용성 증가: 팩토리의 인터페이스와 제품의 인터페이스를 정의함으로써 해당 인터페이스를 구현하는 다양한 제품 및 팩토리를 손쉽게 추가할 수 있어 코드의 재사용성이 증가합니다.
단점
- 복잡성 증가: 팩토리와 제품의 인터페이스 정의, 그리고 각각의 구현체들을 만들어야 하므로 코드의 양이 증가하고 복잡성이 높아질 수 있습니다.
- 단일 책임 원칙 위반 가능성: 팩토리가 제품을 생성하는 역할뿐만 아니라 어떤 제품을 생성할지에 대한 결정도 내릴 수 있습니다.
- 새로운 종류의 제품이 추가도리 때 수정 필요: 새로운 종류의 제품이나 팩토리가 추가될 때마다 클라이언트 코드에 수정이 필요합니다. 이는 개방-폐쇄 원칙을 위반할 수 있습니다.
추상 팩토리 패턴을 주로 객체 생성 로직이 복잡하고 다양한 상황에서 유연성이 요구되는 경우에 적합한 디자인 패턴입니다.
'Computer Science > Design Pattern' 카테고리의 다른 글
[Design Pattern] 빌더 패턴(Builder Pattern)에 대해서, @Builder - 컴도리돌이 (0) | 2024.05.05 |
---|---|
[Design Pattern] 퍼사드 패턴(Facade Pattern)에 대해서 - 컴도리돌이 (0) | 2024.04.04 |
[Design Pattern] 전략 패턴(Strategy Pattern)에 대해서 - 컴도리돌이 (2) | 2024.04.03 |
[Design Pattern] 데코레이터 패턴(Decorator Pattern)에 대해서 - 컴도리돌이 (0) | 2024.03.18 |
[Design Pattern] 복합체 패턴(Composite Pattern)에 대해서 - 컴도리돌이 (0) | 2024.02.20 |