[ JAVA ] 빌더패턴 ( Builder Pattern )

Wooju Kang ·2025년 6월 25일
post-thumbnail

GIF 출처 : https://www.amigoscode.com/courses/java

🖥 Contents


1 ) 빌더 패턴 ( Builder Pattern ) 이란?

2 ) 빌더 패턴 구조

3 ) 스프링에서 빌더패턴 사용하기




1 ) 빌더 패턴 ( Builder Pattern ) 이란?


: 빌더 패턴 ( Builder Pattern ) 는 『Design Patterns: Elements of Reusable Object-Oriented Software』 에서 처음 등장한 디자인 패턴으로 복잡한 객체를 단계별로 생성한 뒤 , 객체 생성방법을 캡슐화 하는 것을 의미한다.

빌더패턴은 생성자를 setter로 직접 필드 하나하나 주입해주는 방식과 달리 Builder().build()메소드를 통해 한번에 객체를 생성하기 때문에 가독성 향상유지보수의 용이함을 가져올 수 있다.

또한 빌더패턴의 경우 최종 객체의 필드를 final로 선언하기 때문에 불변성을 확보할 수 있는 장점이 있다.




2 ) 빌더 패턴 구조


: 빌더 패턴의 경우 클래스 내부에 클래스를 생성하는 구조를 가진다. 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()메소드를 통해 새로운 객체를 생성한다.




3 ) 스프링에서 빌더패턴 사용하기


스프링에서는 주로 Entity 클래스에서 새로운 객체를 생성할때 사용한다. 기존의 빌더패턴과 달리 적용하고자 하는 클래스 위에 @Builder 어노테이션만 추가해주면 된다.

ex ) User 도메인에서 Builder 패턴 도입

< Entity 클래스 >

@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;
}

< Service 클래스 >

@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;

    }

profile
배겐드 📡

0개의 댓글