Computer Science/디자인 패턴

빌더 패턴(Builder Pattern)

닉네임못짓는사람 2022. 2. 2. 11:34
반응형

빌더 패턴(Builder Pattern)이란?


빌더 패턴은 생성 패턴(ConcretePattern)중 하나로, 객체를 생성하기 위한 방법 중 하나라고 할 수 있다.

이외의 생성 패턴으로는 생성자 패턴, 정적 메서드 패턴, 수정자 패턴 등이 있다.

 

그럼 먼저 빌더 패턴을 사용하는 이유에 대해서 알아보도록 하자.

기존의 생성자만을 사용한 객체 생성의 경우 생성자를 overload 함으로써 불필요한 생성자가 늘어난다거나

생성자에 들어갈 인자가 많아질 경우 이들의 순서를 일일이 맞춰 주어야 하고,

각 값이 어떤 값으로 들어가는지 헷갈릴 여지가 있다는 불편함이 존재한다.

 

예를 들어 Persoon이라는 클래스에 인적사항을 인자로 주어 객체를 생성한다고 생각해보자.

fun main(){
    var gildong = Person("고길동", 30, 175.5, 70.3, "남", "3월 1일")
}

class Person(val name: String, val age: Int, val height: Double, val weight: Double, val gender: String, val birthday: String){
    //..생략..
}

위와 같이 객체 생성을 위해 인자로 몇 가지 값을 주는데 이름이나 성별, 생일등은 문제없어도

나이, 키, 몸무게 등은 봣을 때 한눈에 이게 어떤 값인지 파악하기 힘들다는 단점이 존재한다.

 

빌더 패턴은 이러한 불편함을 해결하여 객체를 보다 명시적이고 명확하게 생성할 수 있도록 해준다.

예제


예제를 통해서 빌더 패턴을 사용해보도록 하자.

class Player private constructor(
    private var name: String,
    private var age: Int,
    private var height: Double,
    private var weight: Double,
    private var gender: String,
    private var birthday: String
){
    class Builder{
        private var name = "Default"
        private var age = 20
        private var height = 170.0
        private var weight = 70.0
        private var gender = "남"
        private var birthday = "1월1일"

        fun setName(name: String): Builder{
            this.name = name
            return this
        }

        fun setAge(age: Int): Builder{
            this.age = age
            return this
        }

        fun setHeight(height: Double): Builder{
            this.height = height
            return this
        }

        fun setWeight(weight: Double): Builder{
            this.weight = weight
            return this
        }

        fun setGender(gender: String): Builder{
            this.gender = gender
            return this
        }

        fun setBirthday(month: Int, day: Int): Builder{
            this.birthday = "${month}월${day}일"
            return this
        }

        fun build() = Player(name, age, height, weight, gender, birthday)
    }

    fun printInfo(){
        println("name : ${name}\nage : ${age}\nheight : ${height}\nweight : ${weight}\ngender : ${gender}\nbirthday : ${birthday}")
    }
}

내부에 Builder클래스를 가지고 있는 Player라는 클래스를 작성한다.

 

Builder클래스는 name, age, height 등 변수들의 기본 값을 가지고 있으며,

set함수를 통해서 각 변수들의 값을 저장하고 builder함수를 통해 이를 적용하여 Player클래스의 객체를 생성한다.

 

fun main(){
    val warrior = Player.Builder()
        .setName("Warrior")
        .setHeight(180.0)
        .setWeight(80.0)
        .build()
    warrior.printInfo()

    val wizard = Player.Builder()
        .setName("Wizard")
        .setGender("여")
        .setBirthday(3, 3)
        .build()
    wizard.printInfo()
}

main함수에서 위와 같이 Builder를 통해 객체를 생성할 수 있다.

글 상단에서 보앗던 생성자를 사용한 객체 생성보다 확실히 명확하고, 가독성이 좋은 것을 볼 수 있다.

 

장단점


장점

  • 객체 생성시 필수 인자와 선택적 인자를 구별할 수 있다.
  • 생성자를 통한 객체 생성보다 명확하고, 가독성이 좋다.
  • 클래스 내부에 불필요한 생성자들을 줄일 수 있다.

단점

  • Bulder클래스를 작성해야 하기해 코드가 길어진다. (Lombok을 사용해 해결 하능)
  • Builder클래스의 객체를 생성하기 때문에 생성자를 사용한 객체 생성보다 성능이 떨어질 수 있다.

 

이상으로 빌더 패턴에 대해서 알아보았다.

반응형