
GIF 출처 : https://www.amigoscode.com/courses/java
1 ) 빌더 패턴 ( Builder Pattern ) 이란?
2 ) 빌더 패턴 구조
3 ) 스프링에서 빌더패턴 사용하기
: 빌더 패턴 ( Builder Pattern ) 는 『Design Patterns: Elements of Reusable Object-Oriented Software』 에서 처음 등장한 디자인 패턴으로 복잡한 객체를 단계별로 생성한 뒤 , 객체 생성방법을 캡슐화 하는 것을 의미한다.
빌더패턴은 생성자를 setter로 직접 필드 하나하나 주입해주는 방식과 달리 Builder().build()메소드를 통해 한번에 객체를 생성하기 때문에 가독성 향상 및 유지보수의 용이함을 가져올 수 있다.
또한 빌더패턴의 경우 최종 객체의 필드를 final로 선언하기 때문에 불변성을 확보할 수 있는 장점이 있다.
: 빌더 패턴의 경우 클래스 내부에 클래스를 생성하는 구조를 가진다. static final 로 선언하여 생성한다.
public record User(int x,int y) {
public static final class Builder{
private int x;
private int y;
public Builder(User user){
this.x = user.x();
this.y = user.y();
}
public Builder x(int x){
this.x = x;
return this;
}
public Builder y(int y){
this.y = y;
return this;
}
public User build(){
return new User(this.x,this.y);
}
}
}
var user = new User(20,30); // User[x=20,y=30]
var updatedUser = new User.Builder(user) // User[x=10,y=20]
.x(10)
.y(20)
.build();
이를 통해 외부에서도 Builder() 메소드를 사용할 수 있고 final을 통해 상속을 막아 불변성과 안정성을 지킬 수 있다. 마지막에 build()메소드를 통해 새로운 객체를 생성한다.
스프링에서는 주로 Entity 클래스에서 새로운 객체를 생성할때 사용한다. 기존의 빌더패턴과 달리 적용하고자 하는 클래스 위에 @Builder 어노테이션만 추가해주면 된다.
ex ) User 도메인에서 Builder 패턴 도입
@Entity
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name="user_username",nullable = false,unique = true)
private String username;
@Column(name="user_password",nullable = false)
private String password;
@Column(name="user_nickname",nullable = false,unique = true)
private String nickname;
@Column(name="user_createDate",nullable = false)
private LocalDateTime createDate;
@Enumerated(EnumType.STRING)
@Column(name="user_level",nullable = false)
private Role role;
}
@Transactional
public UserCreationResponse userCreate
(UserCreationRequest userCreationRequest){
// 중복여부 체크 메소드 먼저 실행
User user = User.builder()
.username(userCreationRequest.username())
.password(bCryptPasswordEncoder.encode(userCreationRequest.password()))
.nickname(userCreationRequest.nickname())
.createDate(LocalDateTime.now())
.role(Role.NORMAL) // 일반 유저의 경우 Role.NORMAL 타입으로 설정
.build();
UserCreationResponse userCreationResponse
= new UserCreationResponse(userCreationRequest.username(),
userCreationRequest.nickname());
userRepository.save(user);
return userCreationResponse;
}