ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 빌더패턴 (Builder Pattern) , @Builder 사용권장, @setter지양이유 (Lombok)
    java 2023. 10. 4. 13:32
    반응형

     

     

     

    들어가기전

    도입

    개념정리

     빌더패턴이란?

     빌더패턴의 탄생배경

     점증적 생성자패턴이란?

     자바빈즈패턴이란?

     빌더패턴의 장점은?

     빌더 패턴의 단점은?

     @Builder란?

    나의 언어로 이해

    출처

     

     

    들어가기전

    이글은 @AllArgsConstructor 등의 내용을 다룬 이전 글과 이어진다.

    @Builder의 내용과 사용방법 그리고 @setter의 사용이 지양되는 이유 등에 대해서 다룰 예정이다.

    아직 공부 단계에서 작성한 글로 내용에 오류가 있을 수 있음을 먼저 알립니다. 잘못된 부분이 있다면 댓글 부탁드립니다.

    도입

    코드를 리팩토링하는 과정에서 무분별하게 사용된 lombok어노테이션들을 정리할 필요성을 느꼈다.

    이전 포스팅에서 다루었던 @AllArgsConstructor 등의 어노테이션들은 치명적인 단점이 있다는 것을 알게 되었고 이를 보완하여 @Builder 사용의 필요성을 느끼게되어 탐색하게 되었다.

     

    개념정리

    빌더패턴이란?

     

    빌더 패턴은 복잡한 객체를 생성하는 방법을 정의하는 클래스와 표현하는 클래스를 별도로 분리하여, 동일한 절차에서도 서로 다른 표현을 생성하는 방법을 제공한다.

    빌더 패턴은 어떤 클래스의 인스턴스를 생성할 때 발생할 수 있는 문제를 개선할 수 있다.

    디자인패턴의 일종으로 생성자에서 인자가 많을 때 고려할만한 패턴이라 볼 수 있다.

     

    빌더패턴의 탄생배경

     

    점증적 생성자패턴이란?

    객체 생성시 매개 변수를 점진적으로 추가하는 빌더패턴의 한 형태이다.

    클래스에 필수로 인자를 받아야 하는 멤버변수와 선택적으로 받아야 하는 경우가 있다.

    이때 인자가 많아질 수록 추가적인 생성자가 많아지고, 어떤 객체에 어떤 인자가 들어가는지 알기 어렵다.

     

    자바빈즈패턴이란?

    이를 보완하기 위해서 나왔으며 생성자의 단점이었던 가독성이 어느정도 해결되지만, 코드량이 늘어나는 문제를 가진 패턴이다.

    이 패턴의 가장 큰 문제는 객체일관성이 손상된다는 점이다. 즉, 객체가 변할 여지가 있다는 것이다.

     

    둘의 단점을 모두 보완해서 나타난것이 바로 빌더패턴이다.

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

     

    빌더패턴의 장점은?

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

     

    빌더 패턴의 단점은?

    • 드 구현이 복잡해질 수 있다.
    • 생성자보다 성능이 좋지 않다. 생성자보다 과정이 많아져 성능이 나빠질 수 있다.

     

    @Builder란?

     

    빌드패턴으로만 사용하면 멤버 필드 별로 함수를 생성해야하는 등 생성자보다 더 번거롭고 해당 클래스에 들어갔을 때 빌더로만 몇십줄을 차지해서 코드 읽기도 불편하다. 그래서 나온 것인 @Builder 어노테이션이다.

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

    클래스 또는 생성자 위에 @Builder어노테이션을 붙여주면 빌더패턴 코드가 빌드된다.

    생성자 상단에 선언시 생성자에 포함된 필드만 빌더에 포함된다.

     

    나의 언어로 이해

     빌더패턴은 유지보수와 객체일관성을 중시하기 위해 사용된다 생각한다.

     빌더패턴을 사용할경우 각 인자가 어떤 의미인지 알기 쉽기 때문에 오류를 줄일 수 있다. 또한, 멤버변수는 점점 늘어날 가능성이 많기 때문에 애초에 빌더패턴으로 사용하는 것이 유지보수면에서도 좋다고 생각한다. 또한 무분별한 setter 사용을 억제하여 객체 일관성을 유지할 수 있다.(이는 빌더패턴만의 장점이라 보기엔 어려운 면이 있긴 하다.)

    @Setter를 사용하지 않거나 최소한으로 사용해야하는 이유는 캡슐화와 불변성의 유지하고자 함이다.

    @Setter를 사용하면 해당 클래스의 인스턴스를 수정할 수 있고, 이러한 변경가능성은 예측 불가능성을 만들어서 협업에서도 어려움이 생긴다. 하지만 불변 객체를 사용하면 객체의 상태가 생성 이후에 변경되지 않아서 예측이 가능하고 안전한 코드가 된다. 또한 @Setter를 사용하면 클래스의 내부 구현이 외부에 노출될 수 있으므로 내부 구현을 감추기 위해서도 사용을 지양해야 한다. 

    이전포스팅에 이어서 @NoArgsConstructor는 @Builder를 사용하면 추가로 적을 필요가 없어지고, @AllArgsConstructor 또는 @RequiredArgsConstructor역시 사용할 필요가 없다. (@Setter가 적용되는 문제도 방지할 겸 사용하지 않는 것이 좋다.)

     

    추가 수정

     

    문제상황

    엔티티클래스에서 @GeneratedValue(strategy = GenerationType.IDENTITY)를 사용해야 하는 상황이 생겼다.

    이는 기본 생성자를 필요로하지만 @Builder만 사용할 경우 기본생성자를 만들어줄 수는 없는 문제가 있다.

    이때 @NoArgsConstructor와 @AllArgsConstructor를 같이 사용한다면 기본 생성자를 만들어줄 수 있다.

    그러나 이를 사용할 경우 외부에서 변경할 가능성이 생겨서 일관성에 문제가 생길 수 있다.

    해결방법

    그러므로 각각의 뒤에 (access = AccessLevel.PROTECTED)를 붙여서 기본생정자를 제외한 모든 필드에 대한 생성자가 외부에서 호출되지 않도록 보장해두는 것이 필요하다.

    - Entity class 일부
    @Entity
    @Getter
    @Builder 
    @NoArgsConstructor(access = AccessLevel.PROTECTED)

    @AllArgsConstructor(access = AccessLevel.PROTECTED)
    @Table(name = "NicknamePosts")
    public class NicknamePosts extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column(name = "postId")
    private Integer postId;

     

     

    참고출처

    https://esoongan.tistory.com/82

     

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

    entity나 Dto객체에 값을 넣어줄때 롬복의 빌더 애노테이션(@Builder)을 종종 사용하곤 하는데 완벽히 이해를 하지 못한것같아 정리해보았다! 빌더패턴이란? 디자인패턴중 하나로, 생성과 표현의 분

    esoongan.tistory.com

    https://code-lab1.tistory.com/337

     

    [디자인패턴] 빌더 패턴(Builder Pattern)이란? 빌더 패턴 예제

    GoF와 이펙티브 자바의 빌더 패턴 빌더 패턴은 "Design Patterns"의 공동 저자 4명을 부르는 GoF(Gang of Four)에서 소개하는 버전과 이펙티브 자바(Effective Java)에서 소개하는 버전이 존재한다. 이 글에서는

    code-lab1.tistory.com

     

    반응형

    댓글

Designed by Tistory.