Tech/Spring | Spring Boot
[Lombok][Java] @Builder 에 대해 알아보자 (Builder Pattern)
싱브이
2024. 9. 12. 13:13
728x90
반응형
스프링 프로젝트에서 entity, DTO 객체에 값을 넣을 때 @Builder를 사용하는데, 무의식적으로 사용하고 있다는 생각이 들어 한번 정리해두면 좋을 것 같았다!
객체 생성을 위해서 생성자 패턴, 자바 빈 패턴(Getter/Setter), 빌더 패턴 등을 사용할 수 있는데 왜 빌더 패턴을 사용해야하는지 한번 보자!
1. 생성자 패턴
객체 생성을 위해 생성자를 사용하는 것이다. 간단한 객체 생성에 효과적이지만, 생성자 매개변수가 많아지면 가독성 제로다.
public class User {
private String name;
private String email;
private String password;
public User(String name, String email, String password) {
this.name = name;
this.email = email;
this.password = password;
}
}
User user = new User("John", "john@example.com", "password");
2. 자바 빈 패턴 (Getter/Setter)
기본 생성자와 getter/setter 메서드를 이용하는 패턴이다. 객체의 상태를 설정하고 읽는데 유용하지만, 필드가 많은 객체라면 번거롭다.
public class User {
private String name;
private String email;
private String password;
// 기본 생성자
public User() {}
// getter와 setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
User user = new User();
user.setName("John");
user.setEmail("john@example.com");
user.setPassword("password");
- @Getter, @Setter을 사용할 수 있다. (기본 생성자는 직접 추가해야한다.)
- @Data를 사용할 수 있다. (@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 포함)
3. 빌더 패턴
객체를 단계별로 생성할 수 있다. 필드가 많은 객체를 생성할 때 유용하다!
public class User {
private String name;
private String email;
private String password;
// 기본 생성자
private User(UserBuilder builder) {
this.name = builder.name;
this.email = builder.email;
this.password = builder.password;
}
// Getter 메서드
public String getName() { return name; }
public String getEmail() { return email; }
public String getPassword() { return password; }
// UserBuilder 클래스
public static class UserBuilder {
private String name;
private String email;
private String password;
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder email(String email) {
this.email = email;
return this;
}
public UserBuilder password(String password) {
this.password = password;
return this;
}
public User build() {
return new User(this);
}
}
}
User user = User.builder()
.name("John")
.email("john@example.com")
.password("password")
.build();
- @Builder 을 사용할 수 있다.
@Builder
아무튼 쉽게 말해서 @Builder는 Builder Pattern을 사용할 수 있게 해주는 어노테이션이다.
위의 코드를 아래와 같이 줄일 수 있다. (편-안)
@Builder
public class User {
private String name;
private String email;
private String password;
}
User user = User.builder()
.name("John")
.email("john@example.com")
.password("password")
.build();
(예제)
내가 프로젝트에서 @Builder를 적용한 부분은 Address-Member의 @ManyToOne 관계에서 사용했다.
회원(Member)은 여러 배송지를 선택할 수 있기 때문에 여러 개의 Address를 가질 수 있다.
회원과 주소 엔티티에 필드가 꽤 있기 때문에 @Builder로 가독성을 높이고자 했고,
@ManyToOne의 관계를 가지기 때문에 Address 객체 생성 후 Member와의 연결이 필요했다 !
. . .
// 새로운 Member 객체 생성
Member member = Member.builder()
.username(userFormDto.getUsername())
.email(userFormDto.getEmail())
.password(passwordEncoder.encode(userFormDto.getPassword()))
.nickname(userFormDto.getNickname())
.phoneNumber(userFormDto.getPhoneNumber())
.role(Role.USER)
.isSocial(false)
.build();
// Address 객체 생성 후 Member와 연결
Address address = Address.builder()
.street(userFormDto.getAddress())
.city(userFormDto.getDetailAddress())
.state(userFormDto.getExtraAddress())
.zipCode(userFormDto.getPostcode())
.member(member) // Address와 Member의 연결 설정
.build();
// Member 객체에 Address 추가
member.getAddress().add(address);
. . .
728x90
반응형