
ννλ‘κ² νλ‘μ νΈλ₯Ό μ§ννλ λμ€μ μ λ§ μ΄μ΄ μλ μ€μλ₯Ό ν΄μ μ κΉ μ½μ§νλ μκ°μ κ°μ§κ³ μλ€.
@Data
@AllArgsConstructor
public class VoteRequest {
private Long selectedOptionId;
private Long memberId;
...
}
// λ¬Έμ μ μ½λ. νλΌλ―Έν°μ μμλ₯Ό μλ‘ λ°κΏμ μ λ¬ν¨...
VoteRequest voteRequest = new VoteRequest(**member.getId(), optionB.getId()**);
μμ κ°μ΄ μμ±λ DTO ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μμ±ν λ μΈμλ₯Ό μλͺ» μ λ¬ν΄μ μ΄μν μ€λ₯κ° λ°μνλλ°, νν λ λ€ Long νμ μ΄λΌ νμ°Έμ ν€λ§Έλ€.
μ΄λ¬ν μ€μλ₯Ό λ€μμ λ μΌμ΄λμ§ μλλ‘ νκ³ μ, μ΄λ Έν μ΄μ λ§ λ¬μλκ³ λμ§λ λͺ¨λ₯΄κ³ μ°λ Builder ν¨ν΄μ λν΄ νμ΅ν΄λ΄€λ€.
λΉλ ν¨ν΄μ΄λ κ°μ²΄μ μμ± κ³Όμ κ³Ό νν λ°©λ²μ λΆλ¦¬νμ¬ λ€μν ꡬμ±μ μΈμ€ν΄μ€λ₯Ό λ§λλ μμ± ν¨ν΄μ΄λ€.
μλ₯Ό λ€μ΄ μ§μ μ§λλ€κ³ ν λ, μ΄λ€ μ§μ λͺ©μ¬λ₯Ό μ¬μ©νκ³ λ€λ₯Έ μ§μ μ½ν¬λ¦¬νΈλ₯Ό μ¬μ©ν μ μλ€. μ΄λ κ² μ§μ μ§λ κ³Όμ (μμ± κ³Όμ )μ΄ λ€λ₯΄λλΌλ μμ±λ λͺ¨μ΅μ μ§μ΄λΌλ 곡ν΅μ μΈ νν(νν λ°©λ²)λ₯Ό λκ² λ κ²μ΄λ€.
μ΄μ²λΌ λΉλ ν¨ν΄μ κ°μ²΄μ μμ± κ³Όμ κ³Ό νν λ°©λ²μ΄λΌλ λ κ΄μ¬μ¬λ₯Ό λΆλ¦¬νμ¬ μ μ§ λ³΄μλ₯Ό μ©μ΄νκ² λ§λ λ€.
μ μΈ΅μ μμ±μ ν¨ν΄μ νμ λ§€κ°λ³μμ ν¨κ» 0κ°λΆν° 1κ°, 2κ°μ© μ μ°¨ μ¦κ°νλ μ ν λ§€κ°λ³μλ₯Ό λ°λ ννλ€.
μ¦, λ€μν λ§€κ°λ³μλ₯Ό μ λ¬ λ°μ μΈμ€ν΄μ€λ₯Ό μμ±νκ³ μΆμ λ κΈ°μ‘΄μ μ¬μ©νλ μμ±μλ₯Ό μ€λ²λ‘λ©νλ λ°©μμ΄λ€.
class Sandwich {
// νμ
private String bread;
private String bacon;
// μ ν
private String source;
private String cheese;
private String tomato;
private String lettuce;
public Sandwich(String bread, String bacon) {
this.bread = bread;
this.bacon = bacon;
}
public Sandwich(String bread, String bacon, String tomato) {
this.bread = bread;
this.bacon = bacon;
this.tomato = tomato;
}
public Sandwich(String bread, String bacon, String source, String cheese) {
this.bread = bread;
this.bacon = bacon;
this.source = source;
this.cheese = cheese;
}
...
}
μ΄λ¬ν μ μΈ΅μ μμ±μ ν¨ν΄μλ λͺ κ°μ§ λ¨μ μ΄ μ‘΄μ¬νλ€.
ν΄λμ€μ νλ κ°μκ° μ¦κ°ν μλ‘ μμ±μμ λ€μ΄κ° μ μλ μΈμ μκ° μ¦κ°νκ² λλλ°, μ΄λ κ² λλ©΄ μμ±μμ λͺ λ²μ§Έ μΈμκ° μ΄λ€ νλμλμ§ ν·κ°λ¦¬λ λ¬Έμ κ° λ°μνλ€.
(λ΄κ° μ΄λ²μ λΉλ ν¨ν΄μ νμ΅νκ² λ κ·Όλ³Έμ μΈ μμΈμ΄λ€β¦π₯²)
μ μμ μμ μλμμΉλ₯Ό λ§λ€ λ λΉ΅κ³Ό ν λ§ν λ§ λ£κ³ μΆμ κ²½μ° μλ μμ±μμμ bacon λΆλΆμ μ΄μ© μ μμ΄ nullμ μ λ¬ν΄μΌ νλ€.
public Sandwich(String bread, String bacon) {
this.bread = bread;
this.bacon = bacon;
}
βμ μΈ΅μ μμ±μβλΌλ μ΄λ¦μμ μ μ μλ―, νμ μ΄ λ€μν μλ‘ μμ±μκ° κΈ°νκΈμμ μΌλ‘ μ¦κ°νλ€. μ΄λ κ°λ μ±μ λ¨μ΄λ¨λ¦¬λ©° μ μ§ λ³΄μ μΈ‘λ©΄μμλ κ΅μ₯ν μ’μ§ μλ€.
μμμ μ΄ν΄λ³Έ μ μΈ΅μ μμ±μ ν¨ν΄μ λ¨μ μ 보μνκΈ° μν΄ κ³ μλ ν¨ν΄μΌλ‘, λ§€κ°λ³μκ° μλ μμ±μλ‘ κ°μ²΄λ₯Ό μμ±ν ν setterλ₯Ό μ΄μ©ν΄ νλλ₯Ό μ΄κΈ°ννλ λ°©μμ΄λ€.
class Sandwich {
...
public Sandwich() {
}
public void setBread(String bread) {
this.bread = bread;
}
public void setBacon(String bacon) {
this.bacon = bacon;
}
// 무μν setterλ€...
}
μλ° λΉ ν¨ν΄μ μ μΈ΅μ μμ±μ ν¨ν΄μ λ¨μ μ μ΄λ»κ² 보μνμκΉ?
μ΄μ²λΌ setterλ₯Ό μ¬μ©νλ©΄ μ μ°ν κ°μ²΄λ₯Ό μμ±ν μ μμ§λ§, μλ° λΉ ν¨ν΄λ μΉλͺ μ μΈ λ¨μ μ΄ μ‘΄μ¬νλ€.
μΌκ΄μ±(consistency)
νμ λ§€κ°λ³μλ κ°μ²΄κ° μ΄κΈ°νλ λ λ°λμ μ€μ λμ΄μΌ νλ€. νμ§λ§ κ°λ°μκ° μ€μλ‘ νμ λ§€κ°λ³μμ setterλ₯Ό μμ±νμ§ μκ±°λ νΈμΆνμ§ μμ κ²½μ° ν΄λΉ κ°μ²΄μ μΌκ΄μ±μ΄ 무λμ§κ² λλ€.
μ΄μ²λΌ μΌκ΄μ±μ΄ 무λμ§ κ°μ²΄λ₯Ό λ§μ½ λ€λ₯Έ κ³³μμ μ¬μ©νκ² λλ©΄ λ°νμ μμΈκ° λ°μν κ²μ΄λ€.
λΆλ³(immutable)
μΈλΆμ μΌλ‘ setterλ₯Ό λ ΈμΆνκ² λλ©΄, λκ΅°κ° κ³ μλ‘ setterλ₯Ό νΈμΆν΄μ κ°μ²΄λ₯Ό μ‘°μν μ μκ² λλ€. μ¦, κ°μ²΄κ° μΈμ λ μ§ λ³ν μ μλ μνμ΄ μλ€.
μ μΈ΅μ μμ±μ ν¨ν΄κ³Ό μλ° λΉ ν¨ν΄μ λͺ¨λ λ¬Έμ λ€μ ν΄κ²°νκΈ° μν΄ λλμ΄ λΉλ ν¨ν΄μ΄ λ±μ₯νλ€.
λΉλ ν¨ν΄μ λ³λμ ν΄λμ€(Builder)λ₯Ό λ§λ€μ΄ λ©μλλ₯Ό ν΅ν΄ κ°μ νλνλ μ λ¬ λ°κ³ , μ΅μ’ μ μΌλ‘ νλμ μΈμ€ν΄μ€λ₯Ό μμ±νμ¬ λ°ννλ λ°©μμ΄λ€.
μμ λ₯Ό ν΅ν΄ λΉλ ν¨ν΄μ ꡬ쑰λ₯Ό μ΄ν΄λ³΄μ.
κ²μκΈμ μλ―Ένλ Post ν΄λμ€λ λ©€λ² λ³μλ‘ μμ΄λ, μ λͺ©, λ΄μ©, μμ±μ, μμ±μΌμ κ°μ§κ³ μμΌλ©°, νλμ μμ±μλ μ‘΄μ¬νλ€.
class Post {
private Long id; // μμ΄λ
private String title; // μ λͺ©
private String content; // λ΄μ©
private String createdBy; // μμ±μ
private LocalDate createdDate; // μμ±μΌ
public Post(Long id, String title, String content, String createdBy, LocalDate createdDate) {
this.id = id;
this.title = title;
this.content = content;
this.createdBy = createdBy;
this.createdDate = createdDate;
}
}
λ€μμΌλ‘ Post ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μμ±νκΈ° μν λΉλ ν΄λμ€λ₯Ό ꡬννλ€.
class PostBuilder {
private Long id; // μμ΄λ
private String title; // μ λͺ©
private String content; // λ΄μ©
private String createdBy; // μμ±μ
private LocalDate createdDate; // μμ±μΌ
public PostBuilder id(Long id) {
this.id = id;
return this;
}
public PostBuilder title(String title) {
this.title = title;
return this;
}
public PostBuilder content(String content) {
this.content = content;
return this;
}
public PostBuilder createdBy(String createdBy) {
this.createdBy = createdBy;
return this;
}
public PostBuilder createdDate(LocalDate createdDate) {
this.createdDate = createdDate;
return this;
}
public Post build() {
return new Post(id, title, content, createdBy, createdDate);
}
}
PostBuilder ν΄λμ€μ λ©€λ² λ³μλ λμ ν΄λμ€μΈ Postμ λ©€λ² λ³μμ λκ°μ΄ ꡬμ±λμ΄ μμΌλ©°, κ° λ©€λ² λ³μμ λν μ΄κΈ°ν λ©μλλ₯Ό ꡬννκ³ μλ€.
μ΄λ κ° μ΄κΈ°ν λ©μλλ κ°λ μ±μ μν΄, κ·Έλ¦¬κ³ κΈ°μ‘΄ setterμ μ°¨λ³νκΈ° μν΄ λ©μλλͺ μ κ°λ¨νκ² νλλͺ μΌλ‘ μ§μ΄μ€λ€. κ·Έλ¦¬κ³ λ©μλμμ μ€μνκ² λ΄μΌν λ λ€λ₯Έ μ μ μκΈ° μμ μ λ°ννλ€λ κ²μ΄λ€. μ΄λ νμ μ€λͺ ν λ©μλ 체μ΄λμ μν κ³Όμ μ΄λ€.
λ§μ§λ§μΌλ‘ μ΅μ’ κ°μ²΄λ₯Ό λ§λ€μ΄μ£Όλ build λ©μλλ₯Ό ꡬννλ€. μ΄ λ©μλλ μ΄κΈ°νν λ©€λ² λ³μλ€μ κ°μ§κ³ Postλ₯Ό μμ±νμ¬ λ°ννλ€.
μ΄μ PostBuilder ν΄λμ€λ₯Ό μ΄μ©ν΄ Post κ°μ²΄λ₯Ό μμ±ν΄λ³΄μ.
public class Main {
public static void main(String[] args) {
Post post = new PostBuilder()
.id(1L)
.title("κ²μκΈ μ λͺ©")
.content("κ²μκΈ λ΄μ©")
.createdBy("νκΈΈλ")
.createdDate(LocalDate.now())
.build();
System.out.println(post);
}
}
PostBuilder ν΄λμ€μ λ©μλλ₯Ό νΈμΆνμ¬ κ°μ μ λ¬ν λ€ μ΅μ’ μ μΌλ‘ build λ©μλλ₯Ό νΈμΆνλ©΄ λ€μκ³Ό κ°μ΄ Post κ°μ²΄κ° μμ±λλ€.

public Post(Long id, **String title = "μ λͺ©"**, String content, ...) {
this.id = id;
this.title = title;
this.content = content;
...
} Python, JS, C++ λ± λ€μ μΈμ΄μμ λν΄νΈ λ§€κ°λ³μλ₯Ό μ§μνμ§λ§, Javaμμλ μ§μνμ§ μλλ€. λ°λΌμ λν΄νΈ λ§€κ°λ³μλ₯Ό ꡬννκΈ° μν΄μλ ν΄λμ€ νλ λ³μμ μ΄κΉκ°μ 미리 μ€μ νκ³ , μ΄κΈ°νλ νλλ λ§€κ°λ³μμμ μ μΈμν¨ μμ±μλ₯Ό λ°λ‘ λ§λ€μ΄μΌ νλ€. νμ§λ§ μ΄λ κ²°κ΅ μ§λμΉ μμ±μ μ€λ²λ‘λ©μΌλ‘ μΈν΄ λ³Έλμ λ¬Έμ λ‘ λλμκ°λ κ²μ΄λ€.class PostBuilder {
private Long id;
private String title = "μ λͺ©"; // default parameter μν μν
private String content;
private String createdBy;
private LocalDate createdDate;
... λΉλ ν¨ν΄μμλ λν΄νΈ λ§€κ°λ³μλ₯Ό ꡬννλ λ°©λ²μ λμΌνλ€. νμ§λ§ λν΄νΈ λ§€κ°λ³μκ° μ€μ λ νλμ λν λ©μλλ₯Ό νΈμΆνμ§ μλ λ°©μμ μ¬μ©νλ©΄, λν΄νΈ λ§€κ°λ³μλ₯Ό μλ΅νκ³ νΈμΆνλ ν¨κ³Όλ₯Ό κ°μ μ μΌλ‘ ꡬνν μ μλ€.Post post = new PostBuilder()
.id(1L)
.title("κ²μκΈ μ λͺ©")
.content("κ²μκΈ λ΄μ©")
.createdBy("νκΈΈλ")
.createdDate(LocalDate.now())
.build();
System.out.println(post);
Post post = new PostBuilder(1L)
.content("κ²μκΈ λ΄μ©")
.createdBy("κΉμ² μ")
.createdDate(LocalDate.now())
.build();μ₯μ λ§ μμ κ² κ°μ λΉλ ν¨ν΄μλ λͺ κ°μ§ λ¨μ μ΄ μ‘΄μ¬νλ€.
μμμ λ΄μ μ μ μλ―μ΄ λΉλ ν¨ν΄μ μ½λλ λ€μ μ₯ν©νλ€.
λ°λΌμ νλ μκ° μ κ³ λ³κ²½ κ°λ₯μ±μ΄ μμΌλ©΄ μ°¨λΌλ¦¬ μ μ ν©ν 리 λ©μλλ₯Ό μ΄μ©νμ.
λ€λ§ APIλ μκ°μ΄ μ§λ μλ‘ λ§€κ°λ³μκ° μ¦κ°νκΈ° λλ¬Έμ μ μ΄μ λΉλ ν¨ν΄μΌλ‘ μμνλκ² λμ μλ μλ€.
λΉλ ν¨ν΄ ꡬ쑰 λΆλΆμμ 보μ¬μ€ Post ν΄λμ€λ μ¬μ€ λ€μκ³Ό κ°μ΄ ꡬνλμ΄μΌ νλ€.
λΉλ ν΄λμ€κ° Postμ λ΄λΆ μ μ ν΄λμ€λ‘ ꡬνλλ©°, Postμ μμ±μλ privateμΌλ‘ μ€μ νλ€.
class Post {
private Long id; // μμ΄λ
private String title; // μ λͺ©
private String content; // λ΄μ©
private String createdBy; // μμ±μ
private LocalDate createdDate; // μμ±μΌ
private Post(Builder builder) {
this.id = id;
this.title = title;
this.content = content;
this.createdBy = createdBy;
this.createdDate = createdDate;
}
public static class Builder {
private Long id; // μμ΄λ
private String title; // μ λͺ©
private String content; // λ΄μ©
private String createdBy; // μμ±μ
private LocalDate createdDate; // μμ±μΌ
public Builder id(Long id) {
this.id = id;
return this;
}
public Builder title(String title) {
this.title = title;
return this;
}
public Builder content(String content) {
this.content = content;
return this;
}
public Builder createdBy(String createdBy) {
this.createdBy = createdBy;
return this;
}
public Builder createdDate(LocalDate createdDate) {
this.createdDate = createdDate;
return this;
}
public Post build() {
return new Post(id, title, content, createdBy, createdDate);
}
}
}
νλμ λΉλ ν΄λμ€λ μ€μ§ νλμ λμ κ°μ²΄ μμ±λ§μ μν΄ μ¬μ©λλ€. λ°λΌμ λ ν΄λμ€λ₯Ό 물리μ μΌλ‘ λ¬Άμ΄λ²λ¦ΌμΌλ‘μ¨ λ ν΄λμ€ κ°μ κ΄κ³λ₯Ό μ½κ² νμ ν μ μκ² λλ€.
λν, λΉλ ν΄λμ€λ₯Ό μ μ ν΄λμ€λ‘ ꡬνν¨μΌλ‘μ¨ μΈλΆ ν΄λμ€μ μΈμ€ν΄μ€ μμ΄λ μμ±ν μ μκ² λλ€.
λ§μ½ λΉλ ν΄λμ€κ° μΌλ° λ΄λΆ ν΄λμ€λ‘ ꡬνλλ€λ©΄, λ΄λΆ ν΄λμ€(Builder) μμ± μ μ μΈλΆ ν΄λμ€(Post)μ μΈμ€ν΄μ€λ₯Ό λ¨Όμ μμ±ν΄μΌ νλ λͺ¨μμ λΉ μ§λ€.
Post ν΄λμ€μ μμ±μλ₯Ό privateμΌλ‘ μ€μ ν μ΄μ λ λμ κ°μ²΄κ° μ€μ§ λΉλμ μν΄ μ΄κΈ°νλκΈ° λλ¬Έμ΄λ€. μ¦, μμ±μλ₯Ό μΈλΆμ λ ΈμΆν νμκ° μκΈ° λλ¬Έμ μμ±μλ₯Ό privateμΌλ‘ μ€μ νλ κ²μ΄λ€.
κ°λ°μκ° λμ± νΈνκ² λΉλ ν¨ν΄μ μ¬μ©ν μ μλλ‘ Lombokμμλ λ³λμ μ΄λ
Έν
μ΄μ
μ μ§μνλλ°, κ·Έκ²μ΄ λ°λ‘ @Builderλ€. λ€μκ³Ό κ°μ΄ ν΄λμ€μ λΆμ¬μ£ΌκΈ°λ§ νλ©΄ λ΄λΆμ λΉλ ν΄λμ€μ builder λ©μλλ₯Ό μμ±λλ€.
@Builder
class Post {
private Long id;
private String title;
private String content;
private String createdBy;
private LocalDate createdDate;
private Post(Builder builder) {
this.id = id;
this.title = title;
this.content = content;
this.createdBy = createdBy;
this.createdDate = createdDate;
}
}
λ€μλ μ΄μ κ°μ μ€μλ₯Ό νμ§ μκ² λ€λ μλ―Έλ‘ λΉλ ν¨ν΄μ κ°λ κ³Ό νμ λ°°κ²½, κ·Έλ¦¬κ³ μ₯λ¨μ κΉμ§ μμλ΄€λ€.
μ§κΈκΉμ§λ λ¨μν μ΄λ Έν μ΄μ λ§ λΆμ΄κ³ μ΄λ»κ² λμκ°λμ§ λͺ°λλλ°, μ΄λ κ² μμ보λ μ΄λ»κ² μ¬μ©ν΄μΌν μ§ λ λͺ ννκ² μλΏμ λ― νλ€.