[Java] ๋น๋ ํจํด(Builder Pattern)
๐ ๋ค์ด๊ฐ๋ฉฐ
๋งค๊ฐ๋ณ์๊ฐ ๋ง์ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ค ๋ณด๋ฉด new Car("Toyota", "Camry", 2022, "Blue", ...)์ฒ๋ผ ๋์ด, ์ด๋ค ๊ฐ์ด ๋ฌด์จ ์ธ์์ธ์ง ํท๊ฐ๋ฆฌ๊ณ ์์๋ฅผ ์ค์ํ๊ธฐ ์ฝ๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด Builder ํจํด์ด๋ค.
Builder ํจํด์ด๋? ๊ฐ์ฒด์ ์์ฑ ๊ณผ์ ์ ๋ณ๋ ํด๋์ค๋ก ๋ถ๋ฆฌํด, ๋ค์ํ ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋จ๊ณ์ ์ผ๋ก ์์ฑํ๋ ํจํด. ํ์ํ ์์ฑ๋ง ๊ณจ๋ผ ์ค์ ํ ์ ์์ด ๊ฐ๋ ์ฑ์ด ์ข๋ค.
์ฅ์ 3๊ฐ์ง:
| ์ฅ์ | ์ค๋ช |
|---|---|
| ๊ฐ๋ ์ฑ ํฅ์ | ๊ฐ ์์ฑ์ ๋ฉ์๋๋ก ์ค์ โ ๋ฌด์จ ๊ฐ์ ๋ฃ๋์ง ๋ช ํ |
| ํ์ฅ์ฑ | ์ ์์ฑ ์ถ๊ฐ ์ ๊ธฐ์กด ์ฝ๋ ๋ณ๊ฒฝ ์ต์ํ |
| ๋ถ๋ณ์ฑ ์ ์ง | ๊ฐ์ฒด๋ฅผ ๋ถ๋ณํ๊ฒ ๋ง๋ค์ด ๋ฉํฐ์ค๋ ๋์์ ์์ |
1. ๊ธฐ๋ณธ ์์
์ ์ ๋ด๋ถ ํด๋์ค Builder๋ฅผ ๋๊ณ , ๊ฐ ์ค์ ๋ฉ์๋๊ฐ ์๊ธฐ ์์ (this)์ ๋ฐํํด ์ฒด์ด๋์ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Car {
private String brand;
private String model;
private int year;
private String color;
private Car(Builder builder) { // ์์ฑ์๋ private
this.brand = builder.brand;
this.model = builder.model;
this.year = builder.year;
this.color = builder.color;
}
public static class Builder {
private String brand;
private String model;
private int year;
private String color;
public Builder(String brand, String model) { // ํ์๊ฐ์ ์์ฑ์๋ก
this.brand = brand;
this.model = model;
}
public Builder year(int year) { this.year = year; return this; } // ์ ํ๊ฐ
public Builder color(String color){ this.color = color; return this; }
public Car build() { // ์ต์ข
๊ฐ์ฒด ์์ฑ
return new Car(this);
}
}
}
// ์ฌ์ฉ ์์
Car car = new Car.Builder("Toyota", "Camry") // ํ์
.year(2022) // ์ ํ
.color("Blue") // ์ ํ
.build();
๐ก ํ์๊ฐ์ Builder ์์ฑ์๋ก, ์ ํ๊ฐ์ ์ฒด์ด๋ ๋ฉ์๋๋ก ๋ฐ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ธ ํจํด์ด๋ค.
2. Lombok์ผ๋ก ๋ ๊ฐ๊ฒฐํ๊ฒ
Lombok์ @Builder ์ ๋
ธํ
์ด์
์ ์ฐ๋ฉด Builder ํด๋์ค๋ฅผ ์๋ ์์ฑํด์ค๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class Car {
private String brand;
private String model;
private int year;
private String color;
}
// ์ฌ์ฉ ์์
Car car = Car.builder()
.brand("Toyota")
.model("Camry")
.year(2022)
.color("Blue")
.build();
์ ๋ ธํ ์ด์ ํ๋๋ก ์์ ์ฅํฉํ Builder ์ฝ๋๋ฅผ ๋์ฒดํ๋, ์ค๋ณต์ ํฌ๊ฒ ์ค์ผ ์ ์๋ค.
3. ํ ๊ฑธ์ ๋ โ Fluent Interface
Builder์ Fluent Interface(๋ฉ์๋ ์ฒด์ด๋์ผ๋ก ๋ฌธ์ฅ์ฒ๋ผ ์ฝํ๋ ์คํ์ผ)๋ฅผ ์ ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ ์์ฐ์ค๋ฌ์์ง๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Car {
private String brand;
private String model;
private int year;
private String color;
private Car() {}
public static CarBuilder builder() {
return new CarBuilder();
}
public static class CarBuilder {
private final Car car = new Car();
private CarBuilder() {}
public CarBuilder brand(String brand) { car.brand = brand; return this; }
public CarBuilder model(String model) { car.model = model; return this; }
public CarBuilder year(int year) { car.year = year; return this; }
public CarBuilder color(String color) { car.color = color; return this; }
public Car build() { return car; }
}
}
// ์ฌ์ฉ ์์
Car car = Car.builder()
.brand("Toyota")
.model("Camry")
.year(2022)
.color("Blue")
.build();
๋ฉ์๋ ํธ์ถ์ด ์ฐ๊ฒฐ๋์ด ์์ฐ์ค๋ฌ์ด ๋ฌธ์ฅ ํํ๋ก ์ฝํ๋, ๊ฐ๋ ์ฑ์ด ์ข์์ง๊ณ ์ฝ๋ ์์ฑ๋ ์ฆ๊ฑฐ์์ง๋ค.
๐ ์ ๋ฆฌ
1
2
3
4
5
6
Builder ํจํด
โโ ๋ชฉ์ ๋งค๊ฐ๋ณ์ ๋ง์ ์์ฑ์์ ๊ฐ๋
์ฑยท์ค์ ๋ฌธ์ ํด๊ฒฐ
โโ ๊ตฌ์กฐ ๋ด๋ถ Builder ํด๋์ค + ์ฒด์ด๋(return this) + build()
โโ ํ์/์ ํ ํ์๊ฐ์ ์์ฑ์, ์ ํ๊ฐ์ ์ฒด์ด๋ ๋ฉ์๋
โโ Lombok @Builder๋ก ์๋ ์์ฑ (์ค๋ณต ์ ๊ฑฐ)
โโ ํ์ฅ Fluent Interface๋ก ๋ฌธ์ฅ์ฒ๋ผ ์ฝํ๊ฒ
| ๊ฐ๋ | ํ ์ค ์ ์ |
|---|---|
| Builder ํจํด | ๊ฐ์ฒด ์์ฑ์ ๋จ๊ณ๋ณ๋ก ๋ถ๋ฆฌํ๋ ๋์์ธ ํจํด |
| ์ฒด์ด๋(return this) | ์ค์ ๋ฉ์๋๊ฐ ์์ ์ ๋ฐํํด ์ฐ๊ฒฐ |
| @Builder | Lombok์ด Builder๋ฅผ ์๋ ์์ฑ |
Builder ํจํด์ โ์์ฑ์ ์ง์ฅโ์ ๋ฒ์ด๋๊ฒ ํด์ฃผ๋ ์ค์ฉ์ ์ธ ํจํด์ด๋ค. ์์ ์๋ฐ๋ก ๊ตฌํํ ์๋ ์์ง๋ง, ์ค๋ฌด์์๋ Lombok์ @Builder ํ ์ค๋ก ๊ฐ๊ฒฐํ๊ฒ ์ฐ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
Comments powered by Disqus.