Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - Swift] 2. 디자인 패턴 (생성 패턴) - 빌더 (Builder) 본문

Design Pattern (디자인 패턴)

[iOS - Swift] 2. 디자인 패턴 (생성 패턴) - 빌더 (Builder)

jake-kim 2022. 12. 28. 22:03

빌더 패턴

  • 인스턴스 생성 시, 필요한 값들에대해 단계적으로 개발자에게 인지를 시키며, 복잡한 생성로직을 사용하는쪽에서 모르게끔하는 방법
    • 팩토리 패턴과 구분) 팩토리 패턴은 매개변수 모두 주입해야 사용 가능하지만, 빌더 패턴은 우선 인스턴스를 생성하고(인스턴스는 default value로 세팅된 상태) 필요한 프로퍼티의 값만 변경
  • 빌더 패턴의 핵심은 확장성
    • House라는 클래스가 있을 때, 코드 여러곳에서 House라는 것을 생성 할 경우, 특정 매개변수들은 항상 동일한 값을 갖는 것이 존재할텐데, 이 값들을 사용하는쪽에서 매번 파라미터로 넘기는 코드가 있다면 지저분한 코드가 될 것
    • House 코드의 인스턴스를 생성할 때 단순히 House() 이렇게 만든 후, 필요한 값들은 setWindows(_:), setDoors(_:)와 같이 채워주면 지저분한 코드 해결이 가능

https://refactoring.guru/ko/design-patterns/builder

코드로 알아보는 빌더 패턴

  • 빌더 패턴이 적용되지 않은 Person 모델
  • 문제점
    • parameter가 늘어나는 경우 -> 사용하는 쪽에서 파라미터가 늘어난 것에대해서 일일이 모두 수정이 필요
    • 사용하는 쪽에서 id, name, age, location 모두 주입해야 생성이 가능 (만약 여러곳에서 사용이 되고, 해당 모델 중 age값이 필요 없는 곳에서도 age값을 넣어주어야 하는 장황한 코드 발생)
class Person {
    var id: String
    var name: String
    var age: Int
    var location: String
    
    init(id: String, name: String, age: Int, location: String) {
        self.id = id
        self.name = name
        self.age = age
        self.location = location
    }
}
  • Builder 패턴으로 리펙토링
    • 사용하는쪽에서는 Builder 인스턴스만 주입해주면 인스턴스 생성 완료되고, 필요한 인스턴스만 따로 변경
protocol PersonBuilderType {
    var id: String { get }
    var name: String { get }
    var age: Int { get }
    var location: String { get }
}

struct PersonBuilder: PersonBuilderType {
    var id = "id"
    var name = "jake"
    var age = 0
    var location = "location"
}

class Person {
    var id: String
    var name: String
    var age: Int
    var location: String
    
    init(builder: PersonBuilderType) {
        id = builder.id
        name = builder.name
        age = builder.age
        location = builder.location
    }
}
  • 사용하는 쪽
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 빌더 패턴 적용 전
        let person = Person(id: "1", name: "jake", age: 0, location: "location")
        
        // 빌더 패턴 적용 후
        let person = Person(builder: PersonBuilder())
        person.id = "1"
    }
}

결론

  • 빌더 패턴은 생성패턴의 하나로, 빌더 패턴을 이용하면 인스턴스의 생성을 담당하는 기능을 빌더에서 사용이 가능하고 생성하는 기능을 따로 두어 관심사의 분리가 되어 결합도를 줄이고 코드의 재사용성을 높이는 장점이 존재
  • 팩토리 패턴와 빌더 패턴 구분하기
  • 팩토리 패턴 
    • 팩토리 패턴은 사용하는 쪽에서 매개변수를 모두 채워주어야 함
    • 사용하는 곳에서 매개변수 값들을 필수로 모두 채워주어야 하는 것일때 사용
  • 빌더 패턴
    • 빌더 패턴은 사용하는 쪽에서 매개변수를 모두 채워주지 않고 바로 생성 가능하며, 필요한 값들은 따로 set하여 사용
    • 사용하는 곳에서 매개변수 값들이 모두 채워주지 않아도 될 때, 코드의 간결성에 이점

* 전체 코드: https://github.com/JK0369/ExBuilderPattern

 

* 참고

https://refactoring.guru/ko/design-patterns/builder

Comments