빌더
- 생성패턴
- 복잡한 객체들을 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 결과도 같은 프로세스를 사용하여 구현할 수 있는 패턴
단일 책임 원칙 - 제품의 비즈니스 로직에서 복잡한 생성 코드를 고립
활용성
- 많은 필드와 중첩된 객체들을 힘들게 단계별로 초기화해야 하는 복잡한 객체 구현
- 합성할 객체들의 표현이 서로 다르더라도 생성 시 이를 지원해야 할 때
구조
요소
- 빌더
- 프로덕트 객체의 일부 소소들을 생성하기 위한 추상 인터페이스 정의
- 구체화 빌더
- 빌더에 정의된 인터페이스 구현, 여러 부품들을 모아 빌더를 복합
- 생성한 요소의 표현을 정의하고 관리
- 제품 검색에 필요한 인터페이스 정의
- 디렉터
- 프로덕트
- 생성할 복합 객체를 표현
- 구체화 빌더는 프로덕트 내부 표현을 구축하고 복합 객체가 어떻게 구성되는지에 관한 절차 정의
장점
- 객체들을 단계별로 생성하거나 생성 단계들을 연기하거나 재귀적으로 단계들을 실행
- 생성과 표현에 필요한 코드를 분리
- 복합 객체를 생성하는 절차를 좀 더 세밀하게 나눌 수 있다.
단점
예시 코드
protocol HttpRequestBuilder {
func method(_ value: String) -> HttpRequestBuilder
func baseURL(_ value: String) -> HttpRequestBuilder
func path(_ value: String) -> HttpRequestBuilder
func body(_ value: String) -> HttpRequestBuilder
func reset() -> HttpRequestBuilder
func request() -> HttpRequestBuilder
}
final class NetworkManager{
func makeNaver(builder: HttpRequestBuilder) -> HttpRequestBuilder {
builder
.reset()
.path("")
.method("get")
.body("")
.baseURL("https://naver.com")
}
func makeKakao(builder: HttpRequestBuilder) -> HttpRequestBuilder {
builder
.reset()
.path("")
.method("get")
.body("")
.baseURL("https://kakao.com")
}
}
class HttpRequest: HttpRequestBuilder {
private var result: Request
init(result: Request) {
self.result = result
}
func method(_ value: String) -> HttpRequestBuilder {
result.method = value
return self
}
func baseURL(_ value: String) -> HttpRequestBuilder {
result.baseURL = value
return self
}
func path(_ value: String) -> HttpRequestBuilder {
result.path = value
return self
}
func body(_ value: String) -> HttpRequestBuilder {
result.body = value
return self
}
func reset() -> HttpRequestBuilder {
result = Request()
return self
}
func request() -> HttpRequestBuilder {
return self
}
}
class Request {
var method: String
var baseURL: String
var path: String
var body: String
init(method: String = "", baseURL: String = "", path: String = "", body: String = "") {
self.method = method
self.baseURL = baseURL
self.path = path
self.body = body
}
}
let manager = NetworkManager()
let request = HttpRequest(result: .init())
let naver = manager.makeNaver(builder: request)
let kakao = manager.makeKakao(builder: request)
print(naver.request())
print(naver.request())
정리
참고