[์ค์ํํธ ๋์์ธํจํด] ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด(Factory Method Pattern)
ํฉํ ๋ฆฌ ํจํด (Factory Pattern)
๋จผ์ ํฉํ ๋ฆฌ ํจํด์ ๋ํด์ ์ ๋ฆฌํด๋ด ์๋ค. ํฉํ ๋ฆฌ ํจํด์ ์ด๋ค ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋, ๊ทธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ฒด์์ ์ง์ ๊ฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ, ํฉํ ๋ฆฌ๋ผ๋ ๊ฐ์ฒด์๊ฒ ๊ทธ ์์ ์ ๋งก๊ฒจ ์์กด์ฑ์ ์ฃผ์ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
ํฉํ ๋ฆฌ ํจํด์ ์ ํ์ํ ๊น์? ํฉํ ๋ฆฌ ํจํด์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ ๊ฐ์ฒด์ ์์ฑ์ ํ ๋ฒ ์บก์ํํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ ๊ฒ ์บก์ํํ์ ๋๋ ๋ ๊ฐ์ง ํจ๊ณผ๋ฅผ ์ป์ ์ ์๋๋ฐ์, ์ฒซ๋ฒ์งธ ํจ๊ณผ๋ ์ธ์คํด์ค์ ์์ฑ์ ๋น์ฆ๋์ค ๋ก์ง์ด ๋ผ์ด์์ ๋, ์ด ๋ก์ง์ ์์กด์ฑ์ ๊ฐ์ง๋ ๊ฐ์ฒด๋ก๋ถํฐ ๋ถ๋ฆฌํ ์ ์๋ค๋ ๊ฒ์ด๊ณ , ๋๋ฒ์งธ ํจ๊ณผ๋ ๋คํ์ฑ์ ํตํด ์ธ์ ๋ ์ง ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ํฉํ ๋ฆฌ๋ฅผ ์ ์ฐํ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
๋ง์ฝ ์ด๋ค ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ๊ณผ์ ์ด ๋ฐ๋๋ค๊ณ ํ๋๋ผ๋, ์์กด์ฑ์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด๋ ์์ ํ์ง ์์ ์ฑ๋ก ํฉํ ๋ฆฌ์ ์๋๋ฆฌ์ค๋ง ์์ ํด์ค ์ ์์ฃ . ๋ง์ฝ ์์กด์ฑ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ด ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๋ค๊ณ ํ๋ค๋ฉด, ์ฌ๋ฌ ์ข ๋ฅ์ ํฉํ ๋ฆฌ๋ฅผ ๊ตฌํํด๋๊ณ ํ์ํ ํฉํ ๋ฆฌ๋ฅผ ์ ํํด ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
Head First Design Pattern์ ๋ฐ๋ฅด๋ฉด ํฉํ ๋ฆฌ ํจํด ์์ฒด๋ ๋์์ธ ํจํด์ผ๋ก ๋ณผ ์๋ ์๊ณ , ํฉํ ๋ฆฌ๋ผ๋ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ์ฝ๋๋ฅผ ์ ๋ฆฌํ๋ ํ๋์ ๋ฐฉ๋ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด๊ณผ ์ถ์ ํฉํ ๋ฆฌ ํจํด์ ์ด ํฉํ ๋ฆฌ๋ฅผ ์ฌ์ฉํด ์ ์๋ ๋์์ธ ํจํด์ด๋ผ๊ณ ํฉ๋๋ค. ๊ทธ๋ผ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ๋ํด ์์ธํ ์์๋ณด์๊ตฌ์!
ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด (Factory Method Pattern)
The Factory Method Pattern defines an interface for creating an object. But, let subsclasses decide which class to instantiate. Factory method lets the class defer instantiation to subclass.
ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ํต์ฌ์ ์ค์ ๋ก ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ํฉํ ๋ฆฌ๋ค์ ๋ํด ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ณ , ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ํ์ ํด๋์ค๋ค์ ์ํด ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ๋์์ธ ํจํด์ ๋๋ค.
ํฉํ ๋ฆฌ ๋ฉ์๋๋ ํฉํ ๋ฆฌ์ ์ธํฐํ์ด์ค์์ ์ ์๋๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๋ฉ์๋๋ฅผ ์๋ฏธํด์. ์ฆ, ์ค์ ๋ก ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ตฌ์ฒด์ ์ธ ํฉํ ๋ฆฌ๋ค์ ์ธํฐํ์ด์ค์ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ๊ตฌํํด์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด์ฃ .
์ ๊ทธ๋ฆผ์ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ๊ตฌ์กฐ๋ฅผ ํํํ๊ณ ์์ต๋๋ค. ๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์ํฉ์ ๋ฐ๋ผ ์ฌ๋ฌ ๊ตฌ์ฒด ํ์ , ConcreteProduct์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ์ถ๋ค๋ฉด, Product๋ก ํ์ ๋ค์ ์ถ์ํํ๊ณ , ์ด ์ธ์คํด์ค์ ์์ฑ์ ํฉํ ๋ฆฌ์ธ Creator์๊ฒ ๋งก๊น๋๋ค.
Creator ์ญ์๋ ์ด๋ฅผ ๊ตฌํํ๊ณ ์๋ ๊ตฌ์ฒด ํ์ ์ด ์กด์ฌํด ์ค์ ๋ก ์ธ์คํด์ค์ ์์ฑ์ Creator๋ฅผ ๋ฐ๋ฅด๋ ํ์ ๊ณ์ธต์ ํด๋์ค์ธ ConcreteCreator์์ ์งํ๋ฉ๋๋ค. "ํฉํ ๋ฆฌ ๋ฉ์๋"๋ผ๋ ์ด๋ฆ์ด ๋ถ์ ์ด์ ๋ ์ฌ๋ฌ ํฉํ ๋ฆฌ๋ค์ ํ๋๋ก ์ถ์ํํ๊ณ ์ธ์คํด์ค์ ์์ฑ์ ๋ด๋นํ๋ ๋ฉ์๋๋ฅผ ์ถ์ํํ๋ ๊ฒ์ ์ฃผ์ํ ์ ๋ต์ผ๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ธ ๊ฒ ๊ฐ๋ค์.
๋๋ฌผ์นดํ ๊ตฌํํด๋ณด๊ธฐ
ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ์ด์ฉํด์ ๊ฐ๋จํ ์์๋ฅผ ๋ง๋ค์ด๋ณผ๊น์?
import Foundation
protocol Animal {
var name: String { get set }
func sound()
}
class Dog: Animal {
var name: String
init(name: String) {
self.name = name
}
func sound() {
print("\(name) Bark! ๐ถ")
}
}
class Cat: Animal {
var name: String
init(name: String) {
self.name = name
}
func sound() {
print("\(name) Meow! ๐ธ")
}
}
๋จผ์ ์ด ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉ๋ Concrete Product์ธ Dog ํด๋์ค์ Cat ํด๋์ค๋ฅผ ์ ์ํ๊ณ , ์ด ๋์ ์ถ์ํํ๋ ์ธํฐํ์ด์ค์ธ Animal ํ๋กํ ์ฝ์ ์์ฑํ์ด์. ์ด ํ๋กํ ์ฝ์ด Product๊ฐ ๋๊ฒ ์ฃ .
์ฐ๋ฆฌ๋ ์ด์ Dog ๋ Cat ์ธ์คํด์ค๊ฐ ํ์ํ ๋ ์ง์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง ์๊ณ ํฉํ ๋ฆฌ๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ธฐ๋ฅผ ์ํด์. ๋ฐ๋ผ์ Concrete Creator๋ ์ด๋ค ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ง ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ Dog๋ Cat์ ์์ฑํด์ ๋ฐํํ๋ ํฉํ ๋ฆฌ๊ฐ ๋๊ฒ ์ฃ .
protocol AnimalFactory {
func make(with name: String) -> Animal
}
class RandomAnimalFactory: AnimalFactory {
func make(with name: String) -> Animal {
return Int.random(in: 0...1) == 0 ? Dog(name: name) : Cat(name: name)
}
}
class EvenAnimalFactory: AnimalFactory {
var previousState: Animal.Type?
func make(with name: String) -> Animal {
if previousState == Cat.self {
self.previousState = Dog.self
return Dog(name: name)
} else {
self.previousState = Cat.self
return Cat(name: name)
}
}
}
๋ ์ข ๋ฅ์ ํฉํ ๋ฆฌ๋ฅผ ๋ง๋ค์์ต๋๋ค. ๊ทธ๋ฅ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ ๋ ํฉํ ๋ฆฌ ๋ชจ๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ธฐ ์ํ ๋น์ฆ๋์ค ๋ก์ง์ ๊ฐ์ง๊ณ ์๋๋ฐ์, ์ด๋ ๊ฒ ๋ก์ง์ ๋ถ๋ฆฌํด๋ผ ์ ์๋ ๊ฒ์ด ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ํฐ ์ฅ์ ์ ๋๋ค. RandomAnimalFactory๋ ๋๋คํ๊ฒ ๊ฐ์์ง๋ ๊ณ ์์ด๋ฅผ ์์ฑํ๊ณ , EvenAnimalFactory๋ ์ด์ ์ ์์ฑํ ํ์ ์ ๊ธฐ์ตํด์ ๋๊ฐ์ ๋๋ฌผ์ด ์ฐ๋ฌ์ ๋์ค์ง ์๋๋ก ํ๊ณ ์์ต๋๋ค.
์ด์ ์ด ํฉํ ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ์ธ์คํด์ค๋ฅผ ์ฃผ์ ๋ฐ๋ ํด๋ผ์ด์ธํธ ๊ฐ์ฒด์ธ ๋๋ฌผ์นดํ๋ฅผ ๋ง๋ค์ด๋ณผ๊ฒ์.
class AnimalCafe {
private var animals = [Animal]()
private var factory: AnimalFactory
init(factory: AnimalFactory) {
self.factory = factory
}
func addAnimal(with name: String) {
self.animals.append(self.factory.make(with: name))
}
func printAnimals() {
self.animals.forEach { animal in
animal.sound()
}
}
func change(factory: AnimalFactory) {
self.factory = factory
}
func clear() {
self.animals = []
}
}
๊ตฌํ์ ๊ฐ๋จํ๊ฒ ํ๋๋ฐ์, ์นดํ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์ฌ์ฉํ ํฉํ ๋ฆฌ ๊ฐ์ฒด๋ฅผ ์ฃผ์ ๋ฐ๊ณ , ์๋ก์ด ๋๋ฌผ์ ์ถ๊ฐํ๊ฒ ๋๋ฉด ํด๋น ๋๋ฌผ์ ์ธ์คํด์ค๋ฅผ ํฉํ ๋ฆฌ๋ฅผ ํตํด ๋ง๋ค๊ณ ๋ฐํ๋ฐ์ ๋ฆฌ์คํธ์ ์ถ๊ฐํ๊ณ ์์ต๋๋ค.
let animalCafe = AnimalCafe(factory: EvenAnimalFactory())
animalCafe.addAnimal(with: "A")
animalCafe.addAnimal(with: "B")
animalCafe.addAnimal(with: "C")
animalCafe.addAnimal(with: "D")
animalCafe.addAnimal(with: "E")
animalCafe.addAnimal(with: "F")
animalCafe.printAnimals()
animalCafe.clear()
print("\n## Change Factory ##\n")
animalCafe.change(factory: RandomAnimalFactory())
animalCafe.addAnimal(with: "A")
animalCafe.addAnimal(with: "B")
animalCafe.addAnimal(with: "C")
animalCafe.addAnimal(with: "D")
animalCafe.addAnimal(with: "E")
animalCafe.addAnimal(with: "F")
animalCafe.printAnimals()
์์ ์ฝ๋๋ฅผ ๋ง๋ค๊ณ ๋๋ฌผ์นดํ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ํ ์คํธ๋ฅผ ํด๋ด ์๋ค!
๊ฒฐ๊ณผ๋ ์๋ํ๋๋ก ์ ๋์๋ค์! ์ธ์คํด์ค ์์ฑ์ ๋ํ ์์กด์ฑ์ด ์์ด์ก๊ธฐ ๋๋ฌธ์ ๋ฐํ์์ ์๋ก์ด ํฉํ ๋ฆฌ๋ฅผ ์ฃผ์ ํด์ ์ธ์คํด์ค ์์ฑ์ ์ํ ๋ค๋ฅธ ์ ๋ต์ ์ ํํ ์๋ ์๊ณ , ๋ง์ฝ ๋๋ฌผ ์นดํ์ ์๋ก์ด ๋๋ฌผ์ด ์ถ๊ฐ๋๋๋ผ๋ ๋๋ฌผ์นดํ๋ ์์ ํ ํ์ ์์ด ํฉํ ๋ฆฌ ๋ฉ์๋๋ง ์์ ํ๋ฉด ๋์ผํ๊ฒ ๋๋ฌผ ์นดํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ง๋ฌด๋ฆฌ
ํฉํ ๋ฆฌ ํจํด, ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด, ์ถ์ ํฉํ ๋ฆฌ ํจํด์ด ํญ์ ํท๊ฐ๋ฆฌ์ฃ .. ์ด์ ์ "ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด vs ์ถ์ ํฉํ ๋ฆฌ ํจํด"์ด๋ผ๋ ํฌ์คํธ๋ฅผ ์์ฑํ ์ ์ด ์๋๋ฐ, ๊ณต๋ถํ๋ค๋ณด๋๊น ์๋ชป ์ด ๊ฒ ๊ฐ๋๋ผ๊ตฌ์. ์ผ๋จ ๋น๊ณต๊ฐ๋ก ๋๋ ค๋์์ต๋๋คใ
์ง๊ธ๊น์ง ์ ๋ฆฌํ ๋ด์ฉ์ ํฉํ ๋ฆฌ ํจํด์ ํฉํ ๋ฆฌ๋ผ๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ๋๋ ๊ธฐ๋ฒ์ด๊ณ , ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ์ด ํฉํ ๋ฆฌ๋ฅผ ์ถ์ํํ๊ณ ํฉํ ๋ฆฌ ๋ฉ์๋์ ๋ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํด์ ๊ตฌํ์ฒด๊ฐ ์ด๋ค ์ธ์คํด์ค๋ฅผ ์ด๋ป๊ฒ ์์ฑํ ์ง ๊ฒฐ์ ํ๊ฒ ํ๋ ๋์์ธ ํจํด์ด์์ต๋๋ค.
๋ค์ ํฌ์คํธ์์๋ ์ถ์ ํฉํ ๋ฆฌ ํจํด์ ๋ํด์ ๊ณต๋ถํด๋ณผ๊ฒ์!
์์ง ๋์์ธ ํจํด์ ๋ํ ๊ณต๋ถ๊ฐ ๋ง์ด ๋ถ์กฑํด์ ์๋ชป๋ ์ ๋ณด๊ฐ ์์ ์ ์์ด์. ํน์ ์๋ชป๋ ๋ด์ฉ์ด๋ ์์ ๊ฐ ์๋ค๋ฉด ๊ผญ ์๋ ค์ฃผ์ธ์! ์ ๋ ๋ค์ ๊ณ ๋ฏผํด๋ณด๊ณ ์์ ํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค!
์ค๋๋ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค~!