팩토리 패턴은 무엇인가?
팩토리 패턴은 한 종류의 객체를 만들기 위해서 해당 객체를 생성하는 팩토리 interface를 구현해서 만드는 것이다.
예를 들어 Item을 만드는 Factory 인터페이스가 있다고 해보자.
interface Factory {
fun createItem() : Item
}
위 Factory를 PhoneFactory와 TabletFactory로 구현하면 해당 Factory에서는 Item을 팩토리 종류에 따라 다르게 생성한다.
class PhoneFactory : Factory {
override fun createItem(): Item {
return ..
}
}
class TabletFactory : Factory {
override fun createItem(): Item {
return ..
}
}
추상 팩토리 패턴은 팩토리 패턴과 무엇이 다른가?
팩토리 패턴은 한 종류의 객체를 생성하기 위해 사용되지만, 추상 팩토리 패턴은 연관되거나 의존적인 객체로 이루어진 여러 종류의 객체를 생성하기 위해 사용된다.
또한 팩토리 패턴은 팩토리 인터페이스를 구현하여 그 자체가 하나의 객체를 생성하는데 사용되지만, 추상 팩토리 패턴은 팩토리 객체가 아닌 다른 객체 내부에 구현되어 해당 객체에서 여러 타입의 객체를 생성하기 위해 사용된다.
추상 팩토리 패턴 알아보기
예를 들어 식당에서 음식을 생성하는 FoodAbstractFactory가 있다고 해보자.
interface FoodAbstractFactory {
fun createSauce() : Sauce
fun createSalad() : Salad
fun createStake() : Stake
}
이 식당에서는 요리사(Chef)들이 Food들을 생성하므로 FoodAbstractFactory는 다음과 같이 구현될 수 있다.
class ChefAFoodFactory() : FoodAbstractFactory {
override fun createSauce(): Sauce {
}
override fun createSalad(): Salad {
}
override fun createStake(): Stake {
}
}
이제 이 ChefAFoodFactory는 음식점(Restaurant)에 변수로 들어가서 주문(order)가 들어오면 해당 값을 생성하는 역할을 한다.
class Restaurant() {
val chefA: FoodAbstractFactory = ChefAFoodFactory()
val order(food : Food) {
when(food) {
is Sauce -> {
chefA.createSauce()
}
is Salad -> {
chefA.createSalad()
}
is Stake -> {
chefA.createStake()
}
}
}
}
만약 요리사(Chef)가 ChefA에서 ChefB로 바뀐다고 하면 다음과 같이 FoodAbstractFactory의 구현체만 바꿔주면 된다.
class Restaurant() {
private val chefB: FoodAbstractFactory = ChefBFoodFactory()
val order(food : Food) {
when(food) {
is Sauce -> {
chefB.createSauce()
}
is Salad -> {
chefB.createSalad()
}
is Stake -> {
chefB.createStake()
}
}
}
}
이렇게 Concrete Class의 구현에 의존하지 않고도 서로 연관된 객체로 이루어진 제품군을 생성하는 인터페이스를 구현해 다른 객체 안에 넣어 사용하는 것을 추상 팩토리 패턴이라고 한다.
정리
팩토리 패턴은 그 자체로 하나의 객체를 생성하는 역할을 해서 그 자체가 객체를 생성하는데 사용된다. 하지만 이렇게 객체를 생성할 경우 타입이 다른 다양한 객체를 생성해야 할 경우에 문제가 생기게 되는데, 이를 해결하기 위한 것이 바로 추상 팩토리 패턴이다.
추상 팩토리 패턴은 다양한 요구사항을 interface내부에 메서드로 선언하여 interface를 구현하는 클래스에서 요구사항들을 처리하도록 한다. 또한 그 자체로 사용되는 것이 아닌 다른 객체 내부에서 선언되거나 주입되어 사용된다.