본문 바로가기

Kotlin

[Kotlin] Builder Pattern 대체하기

powered by pixabay

 

안녕하세요.

오늘은 Builder Pattern에 대해 알아보고, 코틀린에서는 이를 어떻게 쉽게 대체하는지 알아보겠습니다.


Builder Pattern

Builder Pattern은 객체를 단계별로 설정하고, 

최종적으로 객체를 생성하는 방식입니다.

 

객체가 복잡하고 여러 인자가 필요할 때,

각 인자들을 설정하는 메서드를 호출하여 객체를 만드는 패턴입니다.

 

Java 예제

여러 프로퍼티를 가지는 객체 Car가 있습니다.

public class Car {
    private String engine;
    private String wheels;
    private String seats;
    private String airConditioning;

    public Car(String engine, String wheels, String seats, String airConditioning) {
        this.engine = engine;
        this.wheels = wheels;
        this.seats = seats;
        this.airConditioning = airConditioning;
    }

    @Override
    public String toString() {
        return "Car [engine=" + engine + ", wheels=" + wheels + ", seats=" + seats + ", airConditioning=" + airConditioning + "]";
    }
}

 

Car 클래스를 만들어주는 CarBuilder 클래스 입니다.

public class CarBuilder {
    private String engine;
    private String wheels;
    private String seats;
    private String airConditioning;

    public CarBuilder setEngine(String engine) {
        this.engine = engine;
        return this;
    }

    public CarBuilder setWheels(String wheels) {
        this.wheels = wheels;
        return this;
    }

    public CarBuilder setSeats(String seats) {
        this.seats = seats;
        return this;
    }

    public CarBuilder setAirConditioning(String airConditioning) {
        this.airConditioning = airConditioning;
        return this;
    }

    public Car build() {
        return new Car(engine, wheels, seats, airConditioning);
    }
}

 

Client에서는 CarBuilder를 사용하여 Car 객체를 만듭니다.

public class Main {
    public static void main(String[] args) {
        // Builder 패턴 사용
        Car car = new CarBuilder()
                .setEngine("V8 Engine")
                .setWheels("Alloy Wheels")
                .setSeats("Leather Seats")
                .setAirConditioning("Automatic Air Conditioning")
                .build();
        
        System.out.println(car);
    }
}

Kotlin 변환

이를 코틀린 문법으로 변환해보면 아래와 같습니다.

data class Engine(val type: String)
data class Wheel(val type: String)
data class Seat(val type: String)

class Car(
    val engine: Engine,
    val wheels: Wheel,
    val seats: Seat,
    val airConditioning: String
)
class CarBuilder {
    private var engine: Engine = Engine("Standard Engine")
    private var wheels: Wheel = Wheel("Standard Wheels")
    private var seats: Seat = Seat("Cloth Seats")
    private var airConditioning: String = "Manual Air Conditioning"

    fun engine(type: String) = apply { engine = Engine(type) }
    fun wheels(type: String) = apply { wheels = Wheel(type) }
    fun seats(type: String) = apply { seats = Seat(type) }
    fun airConditioning(type: String) = apply { airConditioning = type }

    fun build(): Car = Car(engine, wheels, seats, airConditioning)
}
fun main() {
    val car = CarBuilder()
        .engine("V8 Engine")
        .wheels("Alloy Wheels")
        .seats("Leather Seats")
        .airConditioning("Automatic Air Conditioning")
        .build()

    println(car)
}

 

apply function을 통해 builder pattern을 쉽게 구현할 수 있습니다.


Default & Named Arguments

코틀린에서 사용할 수 있는 기능인 Default ArgumentNamed Argument를 이용하면 Builder Pattern을 훨씬 쉽게 구현할 수 있습니다.


Named Argument

함수나 생성자 호출 시 각 인자의 이름을 명시적으로 지정하는 방식입니다.

 

이렇게 하면 인자들의 순서를 신경 쓸 필요 없이,

어떤 인자에 어떤 값을 전달하는지 명확히 알 수 있습니다.

fun createUser(name: String, age: Int, address: String) {
    println("Name: $name, Age: $age, Address: $address")
}

fun main() {
    // Named arguments 사용
    createUser(name = "John", age = 30, address = "123 Main St")
}

Default Argument

함수나 생성자에서 매개변수에 기본값을 지정하여,

호출 시 해당 값을 생략할 수 있도록 하는 기능입니다.

 

만약 기본 값을 제공한 매개변수가 호출 시 생략되면,

기본 값이 자동으로 사용됩니다.

fun createUser(name: String, age: Int = 25, address: String = "Unknown") {
    println("Name: $name, Age: $age, Address: $address")
}

fun main() {
    // Default argument가 적용된 함수 호출
    createUser(name = "John")  // age와 address는 기본값 사용
    createUser(name = "Alice", age = 30)  // address는 기본값 사용
    createUser(name = "Bob", age = 22, address = "456 Elm St")  // 모든 인자를 지정
}

Builder Pattern 대체하기

이 두가지를 활용하면, Builder Pattern을 더욱 손쉽게 구현할 수 있습니다.

data class Car(
    val engine: String = "Standard Engine",
    val wheels: String = "Standard Wheels",
    val seats: String = "Cloth Seats",
    val airConditioning: String = "Manual Air Conditioning"
)

fun main() {
    // Builder Pattern처럼 각 속성을 명시적으로 설정
    val car = Car(
        engine = "V8 Engine",
        wheels = "Alloy Wheels",
        seats = "Leather Seats",
        airConditioning = "Automatic Air Conditioning"
    )

    println(car)
}

 

코틀린에서는 이렇게 쉽게 구현할 수 있기에

Builder Pattern이 거의 사용되지 않습니다.

'Kotlin' 카테고리의 다른 글

[Kotlin] Contract  (0) 2025.04.03
[Kotlin] Generic (3) - 그 외  (2) 2024.12.19
[Kotlin] Generic (2) - 변성  (0) 2024.12.10
[Kotlin] Generic (1) - 제네릭?  (0) 2024.12.10
[Kotlin] 위임 (Delegation)  (2) 2024.11.26