안녕하세요.
오늘은 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 Argument와 Named 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 |