* Builder pattern
- 복잡한 객체의 생성과 표현을 서로 분리해 유사한 타입을 생성하기 위해 동일한 프로세스가 사용될 수 있게 함
- 객체 생성 과정을 단계별로 나누고, 유연하고 가독성 있는 방법으로 복잡한 객체를 생성하는 디자인 패턴
- 주로 많은 매개변수를 가진 객체를 생성하거나, 객체 생성 과정을 다양하게 구성하고자 할 때 사용
- 복잡한 객체를 일관된 방식으로 생성하여 가독성 있게 만들어주고, 객체 생성 과정에 유연성 제공
- 객체 생성에 필요한 다양한 구성 요소들을 분리하여 유지 및 확장이 용이하게 만듦
- 선택적인 매개변수나 기본값이 있는 매개변수 등 처리하기 용이
- 작은 규모의 객체에서는 비효율적
* 구성요소
1. 제품(Product)
- 빌더 패턴을 통해 생성하고자 하는 복잡한 객체를 나타냄
- 일반적으로 이 객체는 여러 속성을 가지며, 이들 속성을 설정하기 위한 setter 메서드 등이 제공
2. 빌더(Builder)
- 제품의 생성 과정을 추상화한 인터페이스 제공
- 제품의 각 속성을 설정하기 위한 메서드들을 포함
- 실제 제품을 생성하는 역할은 아님
3. 구체적인 빌더 (Concreate Builder)
- 빌더 인터페이스를 구현하여 실제로 제품을 생성하는 역할
- 제품을 생성하기 위해 필요한 단계들을 구현, 제품의 속성들을 설정하는 메서드를 구현
4. 디렉터 (Director)
- 빌더를 사용하여 제품을 생성하는 역할
- 빌더의 메서드를 호출하여 제품을 생성하고 조립하는 과정 제어
* 빌더 패턴 활용 예시 1)
import UIKit
class BuilderPatternViewController: UIViewController {
// Pet 구조체 설정
struct Pet {
var name: String? = nil
var age : Int? = nil
}
// PetBuilder 빌더 클래스 설정
class PetBuilder {
private var pet : Pet = Pet()
// 빌더 인스턴스 자신을 반환
func withName(_ name : String) -> Self{
pet.name = name
return self
}
func withAge(_ age : Int) -> Self{
pet.age = age
return self
}
// 최종적으로 Pet 구조체를 생성하고 반환
func build() -> Pet {
return self.pet
}
}
override func viewDidLoad() {
super.viewDidLoad()
let myPet = PetBuilder()
.withName("야옹이")
.withAge(10)
.build()
print(myPet)
}
}
- Pet 구조체가 제품에 해당하며 name, age 속성을 가짐
- PetBuilder 클래스가 빌더에 해당하며, 제품(Pet)의 생성 과정을 추상화한 인터페이스로 제공
- viewDidLoad() 메서드가 디렉터 역할 수행
- 마지막에 build() 함으로써 Pet 구조체를 생성
예시)
import UIKit
class BuilderPatternViewController: UIViewController {
// Pet 구조체 설정
struct Pet {
var name: String? = nil
var age : Int? = nil
init() {}
init(builder : SecondPetBuilder){ //SeconPetBuilder를 인자로 받아 해당 빌더의 속성을 사용하여 Pet 초기화
self.name = builder.name
self.age = builder.age
}
}
class SecondPetBuilder {
var name: String? = nil
var age : Int? = nil
typealias BuilderClosure = (SecondPetBuilder) -> ()
init(buildClosure : BuilderClosure){
buildClosure(self)
}
}
override func viewDidLoad() {
super.viewDidLoad()
let petBuilder = SecondPetBuilder { builder in
builder.name = "댕댕이"
builder.age = 10
}
let mySecondPet = Pet(builder: petBuilder)
print(mySecondPet)
}
}
- init(builder : SecondPetBuilder) : SeconPetBuilder를 인자로 받아 해당 빌더의 속성을 사용하여 Pet 초기화
- viewDidLoad() -> SecondPetBuilder를 이용하여 빌더 인스턴스 petBuilder 생성
- 클로절르 통해 petBuilder의 속성 설정
- petBuilder를 인자로 전달하여 초기화하고 Pet 객체 생성
typealias BuilderClosure = (SecondPetBuilder) -> ()
init(buildClosure : BuilderClosure){
buildClosure(self)
}
}
- 클로저를 이용하여 SecondPetBuilder의 속성을 초기화하는 부분
- typealias : 타입에 대해 별칭을 지정하는 기능
- BuilderClosure라는 새로운 이름으로 '(SecondPetBuilder) -> () ' 타입의 별칭을 정의한 것
- 이 클로저는 SecondPetBuilder를 인자로 받고 반환 값이 없는 클로저
- BuilderClosure를 사용하여 클로저 타입을 표현할 때 해당 별칭을 사용할 수 있음
- 'buildClosure(self)' : buildClosure 클로저를 실행하면서, self 인자로 전달
- self 는 SecondPetBuilder 인스턴스를 나타냄
- 이를 통해 클로저 내에서 SecondPetBuilder의 속성을 설정
참고)
https://www.youtube.com/watch?v=tFOLV35g4Ac
'Swift' 카테고리의 다른 글
Swift - 의존성 주입(Dependency Injection) (0) | 2023.07.10 |
---|---|
Swift - 문서화 (퀵헬프 표시 주석 작성 방법) (0) | 2023.07.09 |
Swift - 디자인 패턴(생성 관련) - 싱글톤 (0) | 2023.07.08 |
Swift - 소프트웨어 아키텍처 (MVP, VIPER) (0) | 2023.07.06 |
Swift - 소프트웨어 아키텍처(MVC, MVVM) (0) | 2023.07.02 |