2 minute read

책 보면서 코딩하다 나온 낯선 코드의 출처를 파해치면서 알게된 개념을 정리했습니다.

'’이게 뭐지’’ 했던 문제의 코드

ResponseDTO<String> response = ResponseDTO
    .<String>builder()
    .data(list)
    .build();

본 포스팅은 아래 블로그를 거의 베꼈습니다.

[[JAVA] 빌더 패턴(Builder Pattern)에 대해 알아보자]: https://lemontia.tistory.com/483

 

왜 쓰는가?

내가 어떤 클래스의 객체를 만듭니다. 클래스의 변수에 어떤 값을 세팅하면서 객체를 만들고자 할 때 우리는 생성자를 이용합니다.

public class UserInfo {
   private String name; //이름
   private int age; //나이
   private String addr; //주소

   public UserInfo(String name, int age, String addr){
       this.name = name;
       this.age = age;
       this.addr = addr;
   }
    
   public String getUserInfo(){
       return String.format("name: %s, age: %d, addr: %s", name, age, addr);
    }
}

 

객체를 사용할 때는 이렇게 합니다.

UserInfo userInfo = new UserInfo("테스터", 25, "서울시 강남구");
System.out.println(userInfo.getUserInfo());

// 결과 => name: 테스터, age: 25, addr: 서울시 강남구

 

근데 만약 주소는 넣지 않겠다. 하면 이렇게 할 수 있습니다.

UserInfo userInfo2 = new UserInfo("테스터", 25, null);
System.out.println(userInfo2.getUserInfo());

// 결과 => name: 테스터, age: 25, addr: null

 

다만 이렇게하면 null 을 입력하는 것은 모양새가 좋지 않으니 추가로 생성자를 만들어 주는 방법이 있겠네요.

 

그런데 만약 요건이 자주 변경된다면 매번 생성자를 만드는 것도 일이 될 것입니다. 위 경우만 보아도 모든 경우의 수를 고려하여 생성자를 만드려면 생성자를 6개나 만들어야 합니다.

그래서 이런 상황을 피하기 위해 좀 더 직관적인 객체를 만들 수 있게 돕는 것이 바로 빌더 패턴 입니다.

 

어떻게 쓰는가?

빌더패턴이 적용된 클래스를 하나 더 만듭니다.

public class UserInfoBuilder {
    private String name;
    private int age;
    private String addr;

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

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

    public UserInfoBuilder setAddr(String addr){
        this.addr = addr;
        return this;
    }

    public UserInfo build(){
        return new UserInfo(name, age, addr);
    }
}

 

객체를 사용할 때는 이렇게 합니다.

UserInfoBuilder userInfoBuilder = new UserInfoBuilder();
UserInfo userInfo3 = userInfoBuilder
        .setName("테스터3")
        .setAddr("주소")
        .setAge(26)
        .build();

System.out.println(userInfo3.getUserInfo());

// 결과 => name: 테스터3, age: 26, addr: 주소

Build를 이용하여 객체를 생성할 때에는 생성자에 들어갈 변수의 순서를 꼭 지키지 않아도 되고,

만약 Name 또는 Age 등 하나를 빼먹어도 Name은 null, Age는 0 등 기본값으로 세팅이 되어 객체가 정상적으로 생성됩니다. (생성자를 이용하는 처음의 코드에서 생성자를 빼먹으면 에러가 납니다.)

 

Lombok을 이용해 더욱 간단하게

Lombok을 사용하는 새로운 클래스를 만들어 보겠습니다.

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class UserInfoLombok {
    private String name;
    private int age;
    private String addr;
}

 

객체는 이렇게 생성합니다.

UserInfoLombok userInfoLombok = UserInfoLombok.builder()
        .name("Lombok 적용")
        .addr("주소 테스트")
        .build();

System.out.println(userInfoLombok);

// 결과=> UserInfoLombok(name=Lombok 적용, age=0, addr=주소 테스트)

위 코드보다 훨씬 간단하게 객체를 생성할 수 있습니다.

 

Categories:

Updated: