[Java]Builder 패턴

LeeYulhee·2023년 8월 28일
0

👉 Builder 패턴이란?


  • 설명

    • 객체 생성과정과 표현 방식을 분리하여 동일한 생성 과정에서 다른 표현 결과를 만들 수 있게 함
      • 객체를 만드는 방법(생성 과정)과 그 객체가 어떻게 나타나야 하는지(표현)를 별도로 관리한다는 뜻
      • 같은 순서와 방법으로 객체를 생성하지만, 결과물의 형태나 표현을 다르게 할 수 있음
    • 주로 복잡한 객체를 생성할 때 사용되며, 생성자에 여러 매개변수가 필요한 경우, 특히 선택적 매개변수가 많을 때 코드의 가독성과 유지 보수를 위해 사용

  • 예시

    • 로봇을 만드는 과정이 항상 같은 경우
      • 먼저 머리를 만들고, 다음에 몸통을 만들고, 그 다음에 팔과 다리를 만듦
    • ⇒ 동일한 생성 과정: 로봇을 만드는 순서는 항상 머리 -> 몸통 -> 팔과 다리
    • ⇒ 다른 표현 결과: 그러나 고객에 따라 로봇의 외형이나 기능을 다르게 할 수 있음



👉 Builder 패턴의 특징


  • 별도의 Builder 클래스를 사용
    • 대체로 대상 객체의 static 내부 클래스로 정의
  • 메서드 체이닝
    • Builder는 자주 체이닝 메서드 방식을 사용하여 각 설정값을 추가
  • 불변성
    • Builder를 사용하여 객체를 한번 생성한 후에는 그 객체의 상태를 변경할 수 없게 하는 것이 일반적



👉 Builder 패턴 예시


public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private String phone;
    private String address;

    private Person(Builder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }

    public static class Builder {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;

        public Builder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

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

        public Builder phone(String phone) {
            this.phone = phone;
            return this;
        }

        public Builder address(String address) {
            this.address = address;
            return this;
        }

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

// 사용 예시
Person person = new Person.Builder("John", "Doe")
                .age(30)
                .phone("123456789")
                .address("Street 123")
                .build();


👉 Builder 패턴의 장단점


  • 장점
    • 가독성 향상
      • 많은 매개변수가 있는 생성자나 setter 메서드를 사용하는 대신, Builder 패턴을 사용하면 객체 생성 코드가 더 읽기 쉬움
    • 객체 불변성
      • 한번 객체가 생성되면 그 상태를 변경할 수 없게 만들 수 있음
    • 선택적 매개변수
      • 필요한 매개변수만 설정하여 객체를 생성할 수 있음

  • 단점
    • 코드 복잡성
      • 간단한 객체의 경우, Builder 패턴이 코드를 복잡하게 만들 수 있음



👉 @Builder와 @SuperBuilder 어노테이션


  • 📌 @Builder 어노테이션

    import lombok.Builder;
    
    @Builder
    public class Burger {
        private boolean lettuce;
        private boolean cheese;
        private boolean tomato;
        private boolean bacon;
    }
    
    // 사용 예시
    Burger burger = Burger.builder()
                    .lettuce(true)
                    .cheese(true)
                    .build();
    • @Builder 어노테이션을 클래스에 붙이면, Lombok이 자동으로 해당 클래스에 대한 Builder 코드를 생성
      • 별도의 Builder 클래스를 수동으로 작성할 필요가 없음

  • 📌 @SuperBuilder 어노테이션

    import lombok.experimental.SuperBuilder;
    
    @SuperBuilder
    class Parent {
        private String parentName;
    }
    
    @SuperBuilder
    class Child extends Parent {
        private String childName;
    }
    
    public class Test {
        public static void main(String[] args) {
            Child child = Child.builder()
                .parentName("John")
                .childName("Doe")
                .build();
        }
    }
    • @SuperBuilder 설명
      • @Builder의 확장된 버전으로, 상속된 클래스 구조에서 Builder 패턴을 사용하고자 할 때 유용
      • @SuperBuilder를 사용할 때는 상속 구조 내에서 모든 관련 클래스에 @SuperBuilder를 적용해야 함
    • 예제 설명
      • 예제에서 Child 클래스는 Parent 클래스를 상속받음
      • @SuperBuilder를 사용함으로써 Child 클래스의 Builder를 통해 Parent 클래스의 필드에도 접근하여 값을 설정할 수 있게 됨

  • 📌 @Builder와 @SuperBuilder의 차이

    • @Builder
      • 간단한 클래스 구조에서 잘 작동
      • 상속된 클래스 구조에서는 부모 클래스의 필드에 대한 접근을 할 수 없음
    • @SuperBuilder
      • 상속 관계에 있는 클래스에서도 Builder 패턴을 적용할 수 있게 도와줌
profile
공부 중인 신입 백엔드 개발자입니다

0개의 댓글