본문 바로가기
스터디/Spring

@Builder를 이용해 Entity <=> DTO 변환하기!

by Big Sun 2022. 12. 1.
728x90

@Builder를 알아보기 전에 빌더 패턴에 대해서 알아보겠습니다.

 

빌더 패턴은 새로운 객체를 만들어내는 방법 중 하나인데, 새로운 객체를 만들어내는 방법은 점층적 생성자 패턴, 자바 빈즈 패턴 그리고, 빌더 패턴등이 있습니다.

 

먼저, 생성자를 통해 새로운 객체를 만드는 방법을 알아보겠습니다.

 

 

  • 클래스용 점층적 생성자 패턴 사용
public class Person {

    private final int age;
    private final String name;
    private final int height;
    private final int weight;
    private final String academicBackground;

    public Person(int age, String name){
        this(age,name,0);
    }

    public Person(int age, String name, int height){
        this(age,name,height,0);
    }

    public Person(int age, String name, int height, int weight){
        this(age,name,height,weight,"jnu");
    }
    public Person(int age, String name, int height, int weight, String academicBackground){
        this.age = age;
        this.name = name;
        this.height = height;
        this.weight = weight;
        this.academicBackground = academicBackground;
    }

}

 

매개변수가 많을 때 점층적 생성자 패턴을 사용하면 매개변수의 순서와 개수를 파악하기 힘듭니다.

 

 

다음으로는 자바 빈즈 패턴에 대해서 알아보겠습니다.

 

 

  • 자바 빈즈 패턴
public class Person {

    private int age;
    private String name;
    private int height;
    private int weight;
    private String academicBackground;

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public void setAcademicBackground(String academicBackground) {
        this.academicBackground = academicBackground;
    }
}

Person person = new Person();
person.setAge(30);
person.setHeight(180);
person.setName("아무개");
person.setWeight(75);
person.setAcademicBackground("아무대");

 

자바 빈즈 패턴과 같은 경우에는 객체 하나를 만들기 위해서, 메서드를 여러개 사용해야하고, 객체가 완전히 생성되기까지 일관성이 지켜지지 않으며 불변객체 또한 만들 수 없습니다.

 

따라서, 위와 같은 단점을 보완해주는 빌더 패턴을 사용합니다.

 

 

빌더 패턴


 빌더 패턴은 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다.

 

동일한 생성 절차라는 의미는 builder()메서드를 호출하고, 이후에 매개변수를 세팅해주는 절차입니다.

그리고, 매개변수를 몇 개를 사용하냐에 따라서 결과가 달라집니다.

 

package effectivejava;

public class Person {

    private final int age;
    private final String name;
    private final int height;
    private final int weight;
    private final String academicBackground;

    public static class Builder{

        private int age;
        private String name;
        private int height;
        private int weight;
        private String academicBackground;

        public Builder age(int age) {
            this.age = age;
            return this;
        }

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

        public Builder height(int height){
            this.height = height;
            return this;
        }

        public Builder weight(int weight){
            this.weight = weight;
            return this;
        }

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

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

    }
    private Person(Builder builder) {
        this.age = builder.age;
        this.name = builder.name;
        this.height = builder.height;
        this.weight = builder.weight;
        this.academicBackground = builder.academicBackground;
    }

}

Person person = new Person.Builder()
                .age(30)
                .height(180)
                .weight(74)
                .academicBackground("aaa")
                .name("아무개")
                .build();

 

 

정리하자면, 빌더 패턴은 필요한 데이터만 세팅이 가능하고, 객체에 새로운 속성을 추가하더라도 기존 빌더 패턴을 사용한 객체 생성에 영향을 주지 않고, 객체에 새로운 속성을 추가하더라도 기존 빌더 패턴을 사용한 객체에 영향을 주지 않습니다.

 

@Builder 적용


@Builder는 개발자가 쉽게 빌더 패턴을 사용하도록 도와주는 애노테이션입니다.

 

빌더 패턴은 위와 같은 특징 때문에, DTO <=> ETNTIY 변환에 사용하기 적합합니다.

 

아래는 제 프로젝트에서 @Builder를 이용해 DTO <=> Entity 변환을 한 예입니다.

 

@Getter
@AllArgsConstructor
@Builder
public class UserSignUpRequest {

    private final String userId;
    private final String userPassword;
    private final String userNickName;
    private final Long userAge;

    public static UserSignUpRequest toDto(User user){
        return UserSignUpRequest.builder()
                .userId(user.getUserId())
                .userPassword(user.getUserPassword())
                .userNickName(user.getUserNickName())
                .userAge(user.getUserAge())
                .build();
    }

    public User toEntity(){
        return User.builder()
                .userId(userId)
                .userPassword(userPassword)
                .userNickName(userNickName)
                .userAge(userAge)
                .build();
    }

}

 

이상입니다!!

728x90