상세 컨텐츠

본문 제목

lombok @Builder (점층적 생성자 패턴, 자바 빈즈 패턴, 빌더 패턴)

Spring/lombok

by Chan.94 2021. 9. 18. 19:41

본문

반응형

[Spring & Spring Boot/lombok] - eclipse(STS)에 lombok 설치

lombok의 @Builder 어노테이션을 알아보기 전에 Builder패턴에 대해 알아야 한다.

 

필자도 @Builder에 정리하던 중 유래(?)에 대해 정리하게 되었다.

 

점층적 생성자 패턴 -> 자바 빈즈 패턴 -> 빌더 패던 -> @Builder


[ Builder 패턴 ]

생성과정과 표현방법을 분리한 패턴을 말하며 점층적 생성자 패턴과 자바 빈즈 패턴의 장점을 섞은 것이 Builder패턴이다.


- 점층적 생성자 패턴 -

Class를 설계하다 보면 필수적인 인자와 비필수적인 인자로 변수가 구분된다.

public class User {

    private String name;    //필수
    private String nickname;//필수
    private String email;   //선택

    public User(String name, String nickname){
        this.name = name;
        this.nickname = nickname
    }

    public User(String name, String nickname, String email){
        this.name = name;
        this.nickname = nickname
        this.email = email;
    }
}

점층적 생성자 패턴의 단점은 다음과 같다.

1. 변수가 많아질수록 생성자가 기하급수적으로 많아질 것이다.

2. 같은 자료형을 가진 변수에 실수로 바꿔서 넣는 경우도 발생할 것이다.

3. 가장 중요한 것은 읽기 어려운 코드가 된다는 것이다.

 

User user = new User("test", "test", "test@naver.com");

위 코드를 설명하기 위해 클래스의 변수명이나 주석을 참조해야 한다.

이러한 점을 보완하기 위해 - 자바 빈즈 패턴 - 이 나왔다.


- 자바빈즈 패턴 -

public class User {

    private String name;    //필수
    private String nickname;//필수
    private String email;   //선택

    public String getName(){
        return this.name;
    } 
    public void setName(name){
        this.name = name;
    }
    public String getNickname(){
        return this.nickname;
    } 
    public void setNickname(Nickname){
        this.nickname= nickname;
    }
    public String getEmail(){
        return this.email;
    } 
    public void setEmail(email){
        this.email= email;
    }
}
User user = new User();
user.setName("test");
user.setNickname("test");
user.setEmail("test@naver.com");

점층적 생성자 패턴의 단점이었던 가독성은 해결된다.

그러나 객체 한 개를 생성하기 위해 여러 번의 메소드를 호출해야 하므로 객체의 일관성이 깨진다.

스레드 작업에 큰 단점이 될 수 있으며, 컴파일 오류는 아니지만 원하지 않는 결과물이 나올 수 있다.

점층적 생성자 패턴과 자바 빈즈 패턴의 장점을 섞은 것이 빌더 패턴이다.

 


 

- Builder 패턴 -

public class User {

    private String name;    //필수
    private String nickname;//필수
    private String email;   //선택

    // setter는 생성하지 않는다
    public String getName(){
        return this.name;
    }
    public String getNickname(){
        return this.nickname;
    } 
    public String getEmail(){
        return this.email;
    } 

    // private 생성자
    private User(Builder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.nickname = builder.nickname;
    }

    // User클래스 안에 선언한 정적 내부 클래스
    public static class Builder {

        private String name;
        private String nickname;
        private String email;

        // name과 nickname은 필수로 입력해야 하는 필드
        public Builder(String name, String nickname) {
            this.name = name;
            this.nickname = nickname;
        }

        public Builder email(String email) {
            this.email= email;
            return this;
        }

        public User build() {
            return new User(this);
        }

    }

}
User user = new User.Builder("홍길동", "길동")
                    .email("test@naver.com")
                    .build();

장점

1. 변수가 많아지더라도 점층적 생성자 패턴보다 가독성이 좋다.

2. Setter를 사용하지 않기에 자바 빈즈 패턴보다 안전하다.

3. 객체의 일관성을 유지할 수 있다.


[ lombok @Builder ]

@Builder(builderMethodName = "") "builder" 메소드명을 재정의 가능

@Builder(builderClassName = "") 내부 클래스 클래스명 (Builder 클래스명)

public class User {

    private String name;    //필수
    private String nickname;//필수
    private String email;   //선택

    @Builder(builderClassName = "UserBuilder1", builderMethodName = "UserBuilder1")
    public User(String name, String nickname, String email) {
        this.name = name;
        this.nickname = nickname;
        this.email = email;
    }
    @Builder(builderClassName = "UserBuilder2", builderMethodName = "UserBuilder2")
    public User(String name, String nickname) {
        this.name = name;
        this.nickname = nickname;
    }
}
User user1 = User.UserBuilder1()
                    .name("홍길동")
                    .nickname("길동")
                    .email("test@naver.com")
                    .build();
User user2 = User.UserBuilder2()
                    .name("이순신")
                    .nickname("순신")
                    .build();

 


lombok 관련 포스팅

[Spring & Spring Boot/lombok] - eclipse(STS)에 lombok 설치

[Spring & Spring Boot/lombok] - lombok 어노테이션

반응형

'Spring > lombok' 카테고리의 다른 글

lombok 어노테이션  (0) 2021.09.17
eclipse(STS)에 lombok 설치  (0) 2021.09.16

관련글 더보기

댓글 영역

>