빌더 패턴(Builder Pattern)을 사용해야 하는 이유

배세훈·2021년 9월 11일
0

java

목록 보기
8/16

빌더 패턴(Builder Pattern)을 사용해야 하는 이유

빌더 패턴의 장점

  1. 필요한 데이터만 설정할 수 있음

예를 들어 User 객체를 생성해야 하는데 age라는 파라미터가 필요 없는 상황이라고 가정
그러면 우리는 age에 더미 값을 넣어주거나 age가 없는 생성자를 새로 만들어 주어야 한다. 이러한 작업이 한번 두번이면 괜찮지만 반복적인 경우에는 시간 낭비로 이어지게 된다. 하지만 빌더를 이용하면 동적으로 이를 처리할 수 있다.

User user = User.builder()
			.name("홍길동")
            .height(180).build();

이렇게 필요한 데이터만 설정할 수 있는 빌더의 장점은 테스트용 객체를 생성할 때 용이하게 해주고 불필요한 코드의 양을 줄이는 등의 이점을 안겨준다.

  1. 유연성을 확보할 수 있음

예를 들어 User 클래스에 몸무게를 나타내는 새로운 변수 weight를 추가해야 한다.

// ASIS
User user = new User("홍길동",180);

// TOBE
User user = new User("홍길동", 180, 75);

새로운 변수 때문에 기존의 코드를 수정해야 하는 상황에 직면하게 된다. 많은 코드가 짜여있었다면 모든 로직을 수정해주거나 생성자를 따로 추가하는 등의 불필요한 조치를 해주어야 한다. 하지만 빌더 패턴을 기반으로 코드가 작성되어 있다면 기존의 코드는 수정할 필요가 없다.

  1. 가독성을 높일 수 있음

ex) 기본 생성자 사용

User user = new User("홍길동", 180, 75);

해당 클래스의 파라미터 값을 바로 파악하기가 힘듬

ex) Builder 패턴 사용

User user = User.builder()
			.name("홍길동")
            .height(180)
            .weight(75).build();
  1. 불변성을 확보할 수 있음

많은 개발자들이 수정자 패턴(Setter)를 흔히 사용한다.
하지만 Setter를 구현한다는 것은 불필요하게 확장 가능성을 열어두는 것이다.
이는 Open-Closed 법칙에 위배되고 불필요한 코드 리딩 등을 유발한다. 그렇기 때문에 클래스 변수를 final로 선언하고 객체의 생성은 빌더에 맡기는 것이 좋다.

생성자의 단점

코드를 읽을 때 각 값의 의미가 무엇인지 헷갈린다.
매개변수가 몇개인지 세어보며 항상 확인해야한다.
타입이 같은 매개변수가 연속으로 있으면 버그 발생 가능성이 높아진다.
실수로 매개변수의 순서가 바뀌더라도 컴파일러가 해당 에러를 잡지 못하여 런타임 에러로 이어지게 된다.

자바빈즈 패턴

매개변수가 없는 생성자로 객체를 만든 후 Setter 메서드들을 호출하여 원하는 매개변수의 값을 설정하는 방식이다. 하지만 여기에는 심각한 단점이 있다.
default 생성자를 통해 객체만 생성하고 필요한 매개변수들을 setter 메소드로 값을 설정해준다고 할 때 만약 설정해야할 매개변수의 수가 많다면 그만큼의 Setter 메소드 호출을 해야하며 객체가 완전히 생성되기 전까지 일관성이 무너진 상태이다.

일관성이 깨진 객체가 만들어지는 것 자체도 런타임시 에러가 발생할 수 잇게되고 디버깅도 어려워진다. 따라서 이러한 문제 때문에 자바빈즈 패턴에서는 클래스를 불변으로 만들 수 없고 스레드 안전성을 얻기 위해서 추가 작업을 해줘야하는 불편함이 있다.

빌더 패턴

빌더 패턴은 저층적 생성자 패턴의 안정성고 자바빈즈 패턴의 가독성을 겸비한 패턴이다.
클라이언트는 필요한 객체를 직접 만드는 대신에 필수 매개변수만으로 생성자 (또는 정적 팩토리)를 호출하여 빌더 객체를 얻는다.
이 빌더 객체가 제공하는 일종의 Setter 메서드들로 원하는 선택 매개변수를 설정한다. 그리고 매개변수가 없는 build 메서드를 호출해 우리에게 필요한 객체를 얻어온다.
빌더 패턴은 상당이 유연하다.
빌더 하나ㅏ로 여러 객체를 순회하면서 만들 수 있고 빌더에 넘기는 매개변수에 따라 다른 객체를 만들 수 있다. 객체마다 부여되는 일련번호와 같은 특정 필드는 빌더가 알아서 채우게 할 수 있다.

ex) 빌더 패턴 예시

public class Test {

    private final String userName;
    private final Long userIdx;
    private final String title;

    public static class Builder {

        private  String userName = "";
        private  String userIdx = "";
        private  String title = "";

        public Builder() {}

        public Builder userName(String userName){
            userName = userName;
            return this;
        }

        public Builder userIdx(Long userIdx){
            userIdx = userIdx;
            return this;
        }

        public Builder title(String title){
            title = title;
            return this;
        }

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

    public Test(Builder builder) {
        userName = builder.userName;
        userIdx = builder.userIdx;
        title = builder.title;
    }
}
Test test = new Test
             .Builder()
             .userName("kimseohae")
             .userIdx(1)
             .title("hello")
             .build();
profile
성장형 인간

0개의 댓글