Backend

Builder Pattern

뭉크테크 2026. 8. 1. 00:06

정의

  • 빌더 패턴은 최종 객체 생성에 필요한 여러 설정값을 Builder 객체에 임시로 저장한 뒤, 그 설정값을 바탕으로 최종 목적 객체를 생성하는 패턴이다.

 

필요한 이유

class Computer(
    val cpu: String,
    val ram: Int,
    val storage: Int,
    val gpu: String?,
    val wifi: Boolean,
    val bluetooth: Boolean
)

val computer = Computer("Intel i7", 32, 1000, "RTX 5070", true, true)
  • 각 값이 무엇인지 코드만 보고 바로 구분하기 힘들며, 매개 변수 순서도 틀릴 가능성 존재한다.(가독성 문제)
  • 선택항목이 많아지면 필요없는 값까지 어쩔 수 없이 null, false, 0 같은 기본값들로 일일이 채워야하는 불편함 또한 존재한다.

 

코드

전체 코드

class Computer private constructor(
    val cpu: String,
    val ram: Int,
    val storage: Int,
    val gpu: String?,
    val wifi: Boolean,
    val bluetooth: Boolean
) {
    class Builder {
        private var cpu: String = ""
        private var ram: Int = 0
        private var storage: Int = 0
        private var gpu: String? = null
        private var wifi: Boolean = false
        private var bluetooth: Boolean = false

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

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

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

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

        fun wifi(wifi: Boolean): Builder {
            this.wifi = wifi
            return this
        }

        fun bluetooth(bluetooth: Boolean): Builder {
            this.bluetooth = bluetooth
            return this
        }

        fun build(): Computer {
            require(cpu.isNotBlank()) { "CPU는 필수입니다." }
            require(ram > 0) { "RAM은 0보다 커야 합니다." }
            require(storage > 0) { "저장 공간은 0보다 커야 합니다." }

            return Computer(cpu, ram, storage, gpu, wifi, bluetooth)
        }
    }
}

 

객체 생성
val computer = Computer.Builder()
    .cpu("Intel i7")
    .ram(32)
    .storage(1000)
    .gpu("RTX 5070")
    .wifi(true)
    .bluetooth(true)
    .build()
  • 객체 생성을 위한 값들을 별도의 Builder 객체 단계적으로 저장한 뒤, 마지막에 최종 객체를 생성한다.

 

 

주 생성자 입력값 선언

class Computer private constructor(
    val cpu: String,
    val ram: Int,
    val storage: Int,
    val gpu: String?,
    val wifi: Boolean,
    val bluetooth: Boolean
)
  • Computer 객체 생성을 위해 위 선언된 변수들을 데이터 타입에 맞춰 빌더 클래스 method에 기입해야한다. 

 

빌더 클래스

 class Builder {
        private var cpu: String = ""
        private var ram: Int = 0
        private var storage: Int = 0
        private var gpu: String? = null
        private var wifi: Boolean = false
        private var bluetooth: Boolean = false

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

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

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

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

        fun wifi(wifi: Boolean): Builder {
            this.wifi = wifi
            return this
        }

        fun bluetooth(bluetooth: Boolean): Builder {
            this.bluetooth = bluetooth
            return this
        }

        fun build(): Computer {
            require(cpu.isNotBlank()) { "CPU는 필수입니다." }
            require(ram > 0) { "RAM은 0보다 커야 합니다." }
            require(storage > 0) { "저장 공간은 0보다 커야 합니다." }

            return Computer(cpu, ram, storage, gpu, wifi, bluetooth)
        }
    }
  • 최종 객체를 생성하기 전에 객체 생성에 필요한 값들을 임시로 저장하기위한 클래스이다.
  • Kotlin 컴파일러는 Computer 라는 클래스 내부에 Builder 라는 중첩 클래스가 있다는 것을 인지하며, JVM에서 실행할 수 있도록 일반적으로 Computer.class와 Computer$Builder.class라는 별도의 클래스 파일로 컴파일한다.
  • Computer.Builder()를 호출하면 최종 객체 생성에 필요한 값들을 저장할 Builder 객체만 생성된다. 이후 cpu(), ram() 등의 메서드를 호출하면 사용자가 전달한 값이 Builder 객체 내부의 각 필드에 저장된다.
    • 이 메서드들은 현재 Builder 객체의 참조값을 가진 this 를 반환하므로 메서드 체이닝이 가능하다. 즉, 하나의 메서드 호출이 끝난 뒤, 동일한 Builder 객체의 참조값이 반환되고 그 반환된 객체를 대상으로 다음 메서드를 연속해서 호출이 가능하다. 
  • 그리고 최종적으로 build() 라는 메서드 호출시, Build 클래스 인스턴스에 저장된 값들을 그대로 Computer 클래스 생성자 호출시 프로퍼티 초기화값으로 사용되기에, 최종적으로 사용자가 Builer 클래스 인스턴스에 설정했던 값들을 가진 Computer 객체를 생성한다.