[디자인패턴] 팩토리 메서드 패턴, 추상 팩토리 패턴
팩토리 패턴은 객체를 생성하는 역할을 별도의 클래스(Factory)에게 위임하는 것이 핵심이다
팩토리 패턴인 팩토리 메서드 (Factory Method) 패턴과 추상 팩토리 (Abstract Factory) 패턴은 Simple Factory를 베이스로 하여, 별도의 클래스를 통해 특정 객체를 생성하도록 한다.
0. Simple Factory
별도의 클래스(Factory)에서 생성자를 호출하도록 하여, 클라이언트 코드에서는 팩토리를 통해 객체를 생성하는 방식이다.
예를 들어, 인터페이스 `Pet`과 이를 구현하는 `Cat`, `Dog` 클래스가 있다고 가정한다.
public interface Pet {
}
public class Cat implements Pet {
}
public class Dog implements Pet {
}
아래와 같이, 일반적인 방법으로 클라이언트에서 객체 생성 시, 클라이언트와 클래스는 직접적인 의존 관계를 갖게 된다.
Pet cat = new Cat();
Pet dog = new Dog();

Simple Factory 방식으로 객체를 생성하면, 클라이언트가 구현 클래스를 직접 의존하는 것이 아니라 Factory를 통하도록할 수 있다.
public interface Pet {
enum Type {
CAT, DOG
}
}
Pet.Type에 따라 다른 객체를 생성하여 반환하는 메서드를 포함하는 `PetFactory` 클래스를 생성한다.
public class PetFactory {
public Pet createPet(Pet.Type petType) {
switch (petType) {
case CAT:
return new Cat();
case DOG:
return new Dog();
default:
throw new IllegalArgumentException("Pet 타입이 아닙니다");
}
}
}
아래와 같이 PetFactory 클래스의 메서드를 통해, 특정 객체(`Cat`, `Dog` 등)를 생성할 수 있게 된다.
PetFactory petFactory = new PetFactory();
Pet cat = petFactory.createPet(Pet.Type.CAT);
Pet dog = petFactory.createPet(Pet.Type.DOG);
이 경우, 클라이언트에서 구현 클래스를 직접 의존하지 않기 때문에, 클래스 이름이 변경되거나 생성자가 변경되는 경우에도 `PetFactory` 내부만 수정하면 된다.

1. 팩토리 메서드 (Factory Method) 패턴
객체 생성방법을 상위 클래스에서 결정하고, 구체적으로 어떤 클래스의 인스턴스를 생성하는지를 하위 클래스에서 결정하도록 하는 디자인 패턴이다.
팩토리 메서드 패턴은 Simple Factory와 마찬가지로, 별도의 클래스(Factory)를 통해 객체를 생성하지만, 변경에 닫혀있다는 점에서 차이가 있다.
Simple Factory는 새로운 클래스를 추가할 때 Factory 클래스를 수정해야 하지만, 팩토리 메서드는 Factory 클래스의 수정없이 확장이 가능하다.

`Product`: 인터페이스
`ConcreteProduct`: 인터페이스 `Product`를 구현한 클래스
`Factory`: 추상 클래스
`ConcreteFactory`: 추상 클래스 `Factory`를 상속받은 클래스
예를 들어, ConcreteProduct의 객체가 생성되는 과정을 보면 아래와 같다.
i) 인터페이스 `Product`를 구현하는 ConcreteProduct 클래스를 정의한다.
public interface Product {
void method1();
}
public class ConcreteProduct implements Product {
@Override
public void method1() {
System.out.println("ConcreteProduct");
}
}
ii) 추상 클래스 `Factory`에서, 객체를 생성하는 방법을 정의한다. (위 그림에서 anOperation())
이때, 실제로 어떤 객체를 생성할지는 추상 메서드로 정의한 상태이다. (위 그림에서 getInstance())
public abstract class Factory {
public Product anOperation() {
Product product = getInstance();
product.method1();
return product;
}
protected abstract User getInstance();
}
iii) 추상 클래스 `Factory`를 상속받는 `ConcreteFactory`를 정의하고, 추상 메서드를 오버라이드하여 특정 객체를 생성하도록 한다. (이 경우, ConcreteProduct 객체를 반환하도록 getInstance()를 오버라이드 하는 것)
public class ConcreteFactory extends Factory {
@Override
protected Product getInstance() {
return new ConcreteProduct();
}
}
iv) ConcreteFactory를 통해, ConcreteProduct 객체를 생성할 수 있다.
Factory factory = new ConcreteFactory();
Product product = factory.anOperation();
이러한 과정으로 객체를 생성하면, 클래스를 추가할 때 기존 코드의 변경이 없어도 된다.
즉, 팩토리 메서드 패턴은 확장에는 열려있고 변경에는 닫혀있는 OCP(개방-폐쇄 법칙)을 따른다.
2. 추상 팩토리 (Abstract Factory) 패턴
추상 팩토리 패턴은 연관성 있는 객체 군이 여러개 있을 경우, 이들을 묶어 추상화하고, 어떤 구체적인 상황이 주어졌을 때 팩토리 객체에서 집합으로 묶은 객체 군을 구현화하는 생성 패턴이다.
예를 들어, 모니터, 마우스, 키보드를 묶은 전자 제품군이 있을 때, 이들을 삼성 제품군, LG 제품군 등과 같이 브랜드에 따라 묶을 수 있다.

`AbstractFactory`: 최상위 공장 클래스로, 여러 개의 제품들을 생성하는 여러 메서드들을 추상화한다.
`ConcreteFactory`: 각각의 타입에 맞는 제품 객체를 반환하도록 메서드를 재정의한다. (ex. SamsungFactory)
`AbstractProduct`: 각 타입의 제품을 추상화한 인터페이스이다. (ex. Monitor)
`ConcreteProduct` (ProductA ~ ProductB): 각 타입의 제품 구현체들로, 팩토리 객체로부터 생성된다. (ex. SamsungMonitor)
팩토리 메서드와 마찬가지로, OCP를 따른다.
※ 팩토리 메서드 패턴과 추상 팩토리 패턴의 차이
| 팩토리 메서드 패턴 | 추상 팩토리 패턴 | |||
| 공통점 | 객체 생성 과정을 추상화한 인터페이스를 제공 객체 생성을 캡슐화하여 구체적인 타입을 감추고, 느슨한 결합 구조를 표방 |
|||
| 차이점 | 구체적인 객체 생성과정을 하위 또는 구체적인 클래스로 옮기는 것이 목적 | 관련있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들 수 있게 하는 것이 목적 | ||
| 한 Factory 당 한 종류의 객체 생성을 지원 | 한 Factory에서 서로 연관된 여러 종류의 객체 생성을 지원 (제품군 생성 지원) | |||
| 메서드 레벨에 초점을 두어, 클라이언트의 ConcreteProduct 인스턴스의 생성 및 구성에 대한 의존을 감소 | 클래스(Factory) 레벨에 초점을 두어, 클라이언트의 ConcreteProduct 인스턴스 군의 생성 및 구성에 대한 의존을 감소 | |||
출처
Factory 패턴 (1/3) - Simple Factory
1. Overview Factory 패턴은 객체 생성 역할을 별도의 클래스 (Factory) 에게 위임하는 것이 가장 궁극적인 목표입니다. 디자인 패턴 중 Facotry 와 관련된 패턴은 크게 두 가지가 있습니다. 팩토리 메서드
bcp0109.tistory.com
Factory 패턴 (2/3) - Factory Method (팩토리 메서드) 패턴
1. Overview Factory 패턴은 객체 생성과 관련된 디자인 패턴입니다. 1편에서 봤던 Simple Factory 는 객체 생성 역할을 담당하면서 각 클라이언트에서 구현 클래스에 직접 의존하지 않도록 분리했습니다.
bcp0109.tistory.com
💠 추상 팩토리(Abstract Factory) 패턴 - 완벽 마스터하기
Abstract Factory Pattern 추상 팩토리 패턴은 연관성이 있는 객체 군이 여러개 있을 경우 이들을 묶어 추상화하고, 어떤 구체적인 상황이 주어지면 팩토리 객체에서 집합으로 묶은 객체 군을 구현화
inpa.tistory.com