팩토리 메서드 패턴은 Creational Pattern 종류 중 하나로,
객체의 생성을 서브클래스가 하도록 하는 패턴
팩토리 메서드 패턴은 아래의 4가지 객체를 통해 구현할 수 있다.
[1] Product
공통의 프로퍼티와 메서드를 가지는 인터페이스 객체
팩토리의 팩토리 메서드를 통해 생성되는 모든 객체들에 대한 공통 인터페이스이다.
[2] Concrete Product
이름의 콘크리트처럼, Product를 구현한 최종의 객체를 의미한다.
Product를 준수한다면 해당 Concrete Product는 무한히 생성될 수 있다.
실제 소스코드 변경에서도 Concrete Product와 Factory의 변경만으로 수정이 가능하다.
[3] Creator
위 Product를 준수하는 객체를 생성하는 메소드를 가지고 있는 인터페이스이다.
[4] Factory
실제 접근하여 객체를 생성하도록 Creator를 준수하는 객체이다.
다른 곳에서도 학습했지만,
팩토리 메서드를 이해하는 데는 정의보다 예제를 보면서
직접 자기가 생각하는 프로덕트 객체를 만들어보면서 한 번만 구현해도 쪼금 감이 온다.
나는 "치킨" 이라는 Product를 만들어서 이를 팩토리 객체를 통해 생성하는 것 까지 진행하였다.
/*
팩토리 메서드 패턴
- 정의 : 객체 생성을 서브클래스가 하도록 하는 패턴
1. Product : 생성되는 객체에 대한 인터페이스 (공통 기능)
2. Concrete Product : Product를 구현한 객체
3. Creator : 새로운 객체를 반환하는 팩토리 메서드를 선언, 여기서 반환되는 객체는 반드시 Product를 준수해야한다.
4. Factory : Creator를 구현한 실제 객체를 생성하는 클래스
*/
/*
Product : 생성되는 객체에 대한 인터페이스 (공통 기능)
공통 기능이므로, 공통 기능에 대한 수정만 이곳에서 일어난다.
예 : 치킨
- 필요 공통 기능
1. 치킨 이름 : String
2. 준비물 : [String]
3. 튀김 횟수 : Int
4. 튀김 온도들 : [Int]
5. 치킨 가격 : Int
6. prepare : 치킨을 튀기기전의 준비 과정
7. cook : 치킨을 튀기는 레시피
*/
protocol Chicken {
var name: String { get }
var preparations: [String] { get }
var countOfFries: Int { get }
var fryingTemperatures: [Int] { get }
var price: Int { get }
func prepare()
func cook()
}
extension Chicken {
func prepare() {
print("\(self): \(#function)")
print("준비물")
preparations.forEach { print($0) }
}
func cook() {
print("\(self): \(#function)")
print("\(countOfFries)번 튀긴다.")
for (index, temperature) in fryingTemperatures.enumerated() {
print("\(index + 1)번째는 \(temperature)온도로 튀긴다.")
}
}
}
/*
Concrete Product : 공통 기능을 제공하는 Product 인터페이스를 구현한 실제 객체
해당 객체는 무한히 정의할 수 있다. 새로운 구조체가 생기는 거니까 수정이 있어야한다.
*/
struct OriginalChicken: Chicken {
var name: String {
"\(self)"
}
var preparations: [String] {
["Salt", "Chicken"]
}
var countOfFries: Int {
2
}
var fryingTemperatures: [Int] {
[160, 180]
}
var price: Int {
15000
}
}
struct SpicyChicken: Chicken {
var name: String {
"\(self)"
}
var preparations: [String] {
["Salt", "Chicken", "Pepper"]
}
var countOfFries: Int {
1
}
var fryingTemperatures: [Int] {
[180]
}
var price: Int {
18000
}
}
/*
Creator : Product를 준수하는 객체를 생성하는 팩토리 메서드를 정의한 인터페이스
*/
protocol ChickenCreator {
func getChicken(type: ChickenType) -> Chicken
}
enum ChickenType {
case originalChicken
case spicyChicken
}
/*
Factory : Creator를 준수하는 실제 Product를 생성하는 실 객체를 만드는 객체
새로운 Chicken을 준수하는 Concrete Product가 생성되면 Creator를 구현한 하단의 팩토리 객체에서만 수정하면 생성이 가능하다.
*/
struct ChickenFactory: ChickenCreator {
func getChicken(type: ChickenType) -> Chicken {
switch type {
case .originalChicken:
return OriginalChicken()
case .spicyChicken:
return SpicyChicken()
}
}
}
let chickenFactory = ChickenFactory()
let originalChicken = chickenFactory.getChicken(type: .originalChicken)
let spicyChicken = chickenFactory.getChicken(type: .spicyChicken)
originalChicken.prepare()
originalChicken.cook()
spicyChicken.prepare()
spicyChicken.cook()
결과--
OriginalChicken(): prepare()
준비물
Salt
Chicken
OriginalChicken(): cook()
2번 튀긴다.
1번째는 160온도로 튀긴다.
2번째는 180온도로 튀긴다.
SpicyChicken(): prepare()
준비물
Salt
Chicken
Pepper
SpicyChicken(): cook()
1번 튀긴다.
1번째는 180온도로 튀긴다.
'스위프트' 카테고리의 다른 글
[Network] NWConnection (0) | 2021.10.22 |
---|---|
[개발 용어] API Gateway (0) | 2021.10.11 |
[Swift/Xcode] Framework를 만들고, Import 시키자 (0) | 2021.10.04 |
[Swift] UITextView의 실제 Text영역의 Height를 구해보자 (0) | 2021.09.14 |
[Swift, Objective-C] 유니코드와 문자소에 대해 알아보자 (0) | 2021.09.09 |