달리는 두딘

[JAVA] 빌더 패턴 (Builder Pattern), @Builder 본문

지식노트

[JAVA] 빌더 패턴 (Builder Pattern), @Builder

디두딘 2022. 7. 13. 10:31

빌더 패턴 (Builder Pattern)

정보들은 자바빈즈 패턴처럼 받되, 데이터 일관성을 위해 정보들을 다 받은 후에 객체를 생성한다.

빌더패턴을 적용하면 다음과 같은 장점이 있다.

  • 불필요한 생성자의 제거
  • 데이터의 순서에 상관없이 객체생성 가능
  • 명시적 선언으로 이해하기가 쉽고
  • 각 인자가 어떤 의미인지 알기 쉽다.
  • setter메서드가 없으므로 변경 불가능한 객체를 만들수있다.
  • 한번에 객체를 생성하므로 객체일관성이 깨지지 않는다.
  • build()함수가 null인지 체크해주므로 검증이 가능한다.
  • 안그러면 set하지않은 객체에대해 get을 하게되는경우 nullPointerExcetpion발생 등등의 문제

빌더패턴은 다음과 같이 만들어진다.

  • A클래스 내부에 빌더클래스를 생성한다.
  • 멤버변수별 메서드를 작성하는데, 각 메소드는 변수에 값을 set하고 빌더객체를 리턴한다.
  • build()메서드는 필수 멤버변수의 null체크를 하고 지금까지 set된 builder를 바탕으로 A클래스의 생성자를 호출하고 인스턴스를 리턴한다.
public class PersonInfo {

    private String name;         //필수적으로 받야할 정보

    private int age;             //선택적으로 받아도 되는 정보

    private int phonNumber;      //선택적으로 받아도 되는 정보

    private PersonInfo() {

    }

    public static class Builder {

        private String name;

        private int age;

        private int phonNumber;


        public Builder(String name) { // 필수변수는 생성자로 값을 넣는다.

            this.name = name;

        }

        // 멤버변수별 메소드 - 빌더클래스의 필드값을 set하고 빌더객체를 리턴한다.

        public Builder setAge(int age) {

            this.age = age;

            return this;

        }

        public Builder setPhonNumber(int phonNumber) {

            this.phonNumber = phonNumber;

            return this;

        }

	// 빌더메소드
        public PersonInfo build() {

            PersonInfo personInfo = new PersonInfo();

            personInfo.name = name;

            personInfo.age = age;

            personInfo.phonNumber = phonNumber;
            
            return personInfo;

        }
    }

위와같이 코드를 작성하면 다음과 같이 객체를 생성할 수 있다.

setter에 리턴자료형을 Builder객체로 지정함으로써, 메서드체이닝기법을 적용하고 정보를 다 넣은경우 build()메서드로 객체를 생성한다.
build( ) 메서드를 쓴 이후 에는 PersonInfo 클래스의 멤버변수를 변경 할 수 있는 방법은 리플렉션 기법(동적시점에 변경) 빼곤 존재하지 않는다.

따라서, 데이터 일관성, 객체불변성 등을 만족시킨다. 또한 코드 가독성 역시 올라간다.

PersonInfo personinfo = new PersonInfo
    .Builder("SeungJin")    		// 필수값 입력 ( 빌더클래스 생성자로 빌더객체 생성)
    .setAge(25)  			// 값 set
    .setPhoneNumber(1234)
    .build() 				// build() 가 객체를 생성해 돌려준다.

 

Lombok @Builder

위에서 만든 빌더클래스를 직접 만들지 않아도 롬복플러그인이 지원해주는 어노테이션 하나로 클래스를 생성할 수 있다.

클래스 또는 생성자 위에 @Builder어노테이션을 붙여주면 빌더패턴 코드가 빌드된다.
생성자 상단에 선언시 생성자에 포함된 필드만 빌더에 포함!

@Builder
public class Person {
    private final String name;
    private final int age;
    private final int phone;
}

객체를 다음과 같이 생성할 수 있게된다.

Person person = Person.builder() // 빌더어노테이션으로 생성된 빌더클래스 생성자
    .name("seungjin")
    .age(25)
    .phone(1234)
    .build();



참조 :
johngrib.github.io/wiki/builder-pattern/

mommoo.tistory.com/54