본문 바로가기
개발

[Lombok] @Builder

by angeloper 2023. 6. 30.
반응형

안녕하세요. 오늘은 Lombok의 @Builder라는 부분을 한번 살펴볼 예정입니다.

저번에 @Builder와 @SuperBuilder에 대해서 그렇게 글을 써 놓고 또 쓸게 있냐고 말씀하시는 분들도 계실 텐데요.

네!! 있습니다. (저번에는 사용법에 대해서 제대로 설명도 안 하고, 제가 잊어버릴까 봐 주저리~ 주저리 했네요.)

 

그럼 시작해 볼까요?

 

Lombok은 상용구 코드를 줄이는 데 도움이 되는 도움이 되는 라이브러리라고 하였습니다. 그럼 @Builder라는 주석은 어떻게 사용되고, 어떻게 도움이 되는지 알아보겠습니다.

 

다음과 같은 예시를 통해서 알아보겠습니다.

우선, Person이라는 클래스를 생성해 보겠습니다.

package com.example.builder.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

public class Person {
    private Long id;
    private String name;
    private int age;
}

 

만약, 위와 같은 쿼리가 존재한다면, 보통적으로는 생성자를 통해서 객체를 만들 것입니다. 다음의 코드를 보시죠.

Person class에 대해서 기본생성자와 모든 필드가 존재하는 생성자를 만들었습니다.

(이 부분, 또한 Lombok을 사용하여 생성할 수 있는데 그 부분은 추후에 살펴보겠습니다. 물론, 이전글을 읽으신 분들은 다 아시겠죠?)

package com.example.builder.entity;

public class Person {
    private Long id;
    private String name;
    private int age;

    public Person() {
    }

    public Person(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

그리고, 다음과 같이 객체를 생성하였습니다.

// 1번째 방법 : 기본 생성자를 이용하여 Person 객체를 생성
Person person = new Person();

// 2번째 방법 : 모든 필드를 가지는 생성자를 통하여 객체를 생성
Person person = new Person(1L, "홍길동", 20);

 

그럼 , @Builder Annotation을 사용해 볼까요?

@Builder 클래스, 생성자, 필드 위에 사용할 수 있습니다.

 

1. 클래스 위에 사용해 보기

다음과 같이 코딩한 후, 컴파일된 소스를 확인해 보겠습니다. (참고로 getName 함수는 추후 테스트를 위하여 추가하였습니다.)

 

package com.example.builder.entity;

import lombok.Builder;

@Builder
public class Person {
    private Long id;
    private String name;
    private int age;

    public String getName() {
        return name;
    }
}

 

아래에 보시면, Person에 대하여 전체 필드에 대한 생성자가 만들어져 있으며, 내부에 static class로 PersonBuilder가 생성되어 있는 부분을 확인할 수 있었습니다.

package com.example.builder.entity;

public class Person {
    private Long id;
    private String name;
    private int age;

    public String getName() {
        return this.name;
    }

    Person(final Long id, final String name, final int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public static PersonBuilder builder() {
        return new PersonBuilder();
    }

    public static class PersonBuilder {
        private Long id;
        private String name;
        private int age;

        PersonBuilder() {
        }

        public PersonBuilder id(final Long id) {
            this.id = id;
            return this;
        }

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

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

        public Person build() {
            return new Person(this.id, this.name, this.age);
        }

        public String toString() {
            return "Person.PersonBuilder(id=" + this.id + ", name=" + this.name + ", age=" + this.age + ")";
        }
    }
}

그리고 이제, 테스트를 진행해 보도록 하겠습니다. 아래 테스트 결과 Success가 되었습니다.

 

2. 생성자 위에 사용해 보기

다음과 같이 코딩한 후, 컴파일된 소스를 확인해 보겠습니다.

package com.example.builder.entity;

import lombok.Builder;

public class Person {
    private Long id;
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    @Builder
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

2개 필드만 포함하는 생성자를 만든 후, 컴파일된 소스를 확인해 보니 위의 클래스 위에 사용한 것과 차이가 나지 않는다는 것을 확인하실 수 있습니다. 테스트는 정상적으로 진행되었지만, 페이지가 지루할 수 있으니 Skip 하도록 하겠습니다.

package com.example.builder.entity;

public class Person {
    private Long id;
    private String name;
    private int age;

    public String getName() {
        return this.name;
    }

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

    public static PersonBuilder builder() {
        return new PersonBuilder();
    }

    public static class PersonBuilder {
        private String name;
        private int age;

        PersonBuilder() {
        }

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

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

        public Person build() {
            return new Person(this.name, this.age);
        }

        public String toString() {
            return "Person.PersonBuilder(name=" + this.name + ", age=" + this.age + ")";
        }
    }
}

3. 필드 위에 사용해 보기

필드 위에 사용하는 부분은 @Builder로 사용이 될 수 없으며, @Builder. Default 또는 @Builder.ObtainVia를 사용할 수 있습니다.

  • @Builder.Default : Builder로 객체를 생성 시 기본값을 세팅할 수 있습니다. 
package com.example.builder.entity;

import lombok.Builder;

@Builder
public class Person {
    private Long id;
    private String name;

    @Builder.Default
    private int age = 10;

    public String getName() {
        return name;
    }
}
  • @Builder. ObtainVia : 이 부분에 대해서 정확히 사용하는 방법은 찾는 대로 글을 입력하도록 하겠습니다.

@Builder Annotation을 사용하여 개발자는 일관된 방식으로 인스턴스를 생성하고 속성을 설정할 있으며, 코드 중복을 피할 있다고 생각합니다. 또한, 선택적으로 속성을 설정할 있어 유연성을 제공하며, 코드의 가독성과 유지 보수성을 향상시킬 있습니다. 

 

반응형