정의
- 빌더 패턴(Builder Pattern)은 객체의 생성과 객체 내부에 들어갈 요소들을 분리해내어 “다양한 표현될 수 있는 유연성을 제공”하는 패턴이다.
빌더 패턴 (Builder Pattern) 의 구조

- Builder ⇒
- Product의 속성에 값을 할당하는 메소드로 이루어진 프로토콜 타입
- 해당 프로토콜 내부에는 build() 라는 메소드가 존재하며, 이 메소드는 조립이 완료된 후 Product를 리턴하기 위해 사용되는 메소드이다.
- Concrete Builder ⇒
- Builder 내부에 존재하는 메소드들을 구체적으로 구현하는 영역.
- Director ⇒
- Builder 영역에서 제공하는 메소드를 이용해 다양한 형태의 Product를 조립하는 영역.
- Product ⇒
- Director가 Builder를 이용해 뭔가를 만들어내기 위해 필요로 하는 “기본 양식”
Swift로 빌더 패턴 적용 과정 예시
- 회사 사원들의 프로필을 저장하는 프로그램을 제작한다고 가정해보자. 먼저 신입이 들어올 경우, 저장해야 할 인적사항들을 모아놓은 클래스 객체를 생성한다. 이 객체는 기본 양식으로 이 객체에 Builder를 할당하여 다양한 형태의 인적 프로필을 생성해낼 것이다.
class UserProfile {
var name: String?
var email: String?
var birthdate: Date?
var profilePictureURL: URL?
func describe() {
print("Name: \(name ?? "No name")")
print("Email: \(email ?? "No email")")
print("Birthdate: \(birthdate?.description ?? "No birthdate")")
print("Profile Picture URL: \(profilePictureURL?.absoluteString ?? "No URL")")
}
}
- 프로필의 기본 양식 (Product)에 값을 할당할 메소드를 소유하고 있는 프로토콜 Builder를 생성한다.
protocol UserProfileBuilder {
func setName(_ name: String) -> UserProfileBuilder
func setEmail(_ email: String) -> UserProfileBuilder
func setBirthdate(_ date: Date) -> UserProfileBuilder
func setProfilePictureURL(_ url: URL) -> UserProfileBuilder
func build() -> UserProfile
}
- Builder 내부의 메소드들을 구체적으로 구현하는 Concrete Builder를 생성한다.
class ConcreteUserProfileBuilder: UserProfileBuilder {
private var userProfile = UserProfile()
func setName(_ name: String) -> UserProfileBuilder {
userProfile.name = name
return self
}
func setEmail(_ email: String) -> UserProfileBuilder {
userProfile.email = email
return self
}
func setBirthdate(_ date: Date) -> UserProfileBuilder {
userProfile.birthdate = date
return self
}
func setProfilePictureURL(_ url: URL) -> UserProfileBuilder {
userProfile.profilePictureURL = url
return self
}
func build() -> UserProfile {
return userProfile
}
}
- Builder 영역에서 제공하는 메소드를 이용해 다양한 형태의 사원 프로필을 만들어낼 수 있다.
let builder = ConcreteUserProfileBuilder()
let leo = builder.setName("레오")
.setEmail("leo@example.com")
.setBirthdate(Date())
.setProfilePictureURL(URL(string: "https://example.com/profile.jpg")!)
.build()
let elly = builder.setName("엘리")
.setEmail("elly@example.com")
.setBirthdate(Date())
.setProfilePictureURL(URL(string: "https://example.com/profile.jpg")!)
.build()
leo.describe()
elly.describe()
패턴 사용 시기
- 어떤 클래스 객체 내에 “생성자 매개변수가 너무 많을 때” ⭐️⭐️ 에는 생성자보단 빌더 패턴을 사용할 것을 권장한다.
패턴의 장점
- 생성자 방식으로 객체를 생성할 경우, 매개변수가 많아질 수록 코드의 가독성이 급격하게 떨어지게 된다. 반면 빌더 패턴을 사용하면 훨씬 더 직관적인 코드를 작성할 수 있게 된다.
- 재사용성에 용이하다. (빌더 패턴을 이용해 여러 가지 다양한 객체가 생성될 수 있다.)
패턴의 단점
- 코드의 복잡성이 증가한다. 디자인 패턴의 공통적인 단점이다.
참고 문헌
빌더패턴에서 무조건 할당해야 하는 프로퍼티가 있을 때 해당 값을 할당하도록 강제할 수 있는 방법이 있을까요?
생성자를 사용한다면 생성자 파라미터에 해당 값을 추가해서 객체 생성하려면 무조건 넣게 할 수 있을텐데
빌더패턴은 프로퍼티 할당을 메서드의 호출로 진행하다보니 필수적으로 있어야 하는 프로퍼티인데 할당을 깜빡할 수 있을 것 같아서요