본문 바로가기

Language/JAVA

[이펙티브 자바][아이템 2] 생성자에 매개변수가 많을 때는 빌더를 고려하라 - 컴도리돌이

728x90

개발을 하다 보면 객체를 생성해야 할 때가 당연히 있습니다. 그런데 그 객체를 생성하기 위해 생성자를 사용했는데, 매개변수가 한두 개가 아니라 다섯 개, 여섯 개, 열 개가 넘어갈 때가 있지 않나요? 🤔

 

예를 들어 영양 정보를 담는 NutritionFacts 클래스를 가지고 가정해 볼까요? 

 

public class NutritionFacts {
    private final int servingSize;  // 필수
    private final int servings;     // 필수
    private final int calories;     // 선택
    private final int fat;          // 선택
    private final int sodium;       // 선택
    private final int carbohydrate; // 선택

    public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {
        this.servingSize = servingSize;
        this.servings = servings;
        this.calories = calories;
        this.fat = fat;
        this.sodium = sodium;
        this.carbohydrate = carbohydrate;
    }
}

 

이 클래스는 식품의 서빙 크기, 칼로리, 지방, 나트륨 등의 정보를 담고 있습니다. 처음에는 간단히 new NutritionFacts(240, 8) 이렇게 간편하게 쓸 수 있겠죠. 하지만 시간이 지나면서 더 많은 정보가 필요해지면 어떻게 될까요? 칼로리, 나트륨, 탄수화물, 비타민 수치까지 모두 추가하고 나면, new NutritionFacts(240, 8, 100, 35, 27, 5)와 같은 코드가 나오게 될 겁니다. 😓

 

여기서 문제가 발생해요. 갑자기 매개변수 목록이 너무 길어지면서, 코드만 봐서는 저 숫자가 무엇을 의미하는지 알 수 없게 되죠. 

"100이 칼로리였나? 아니면 27이 탄수화물이었나?"  헷갈리기 시작할 것입니다. 더 심각한 것 매개변수 순서를 실수로 바꾸기라도 하면, 컴파일러는 오류를 잡아주지 않고, 엉뚱한 데이터가 할당되면서 문제가 생길 수도 있다는 거예요.. 😳

 

 

[Design Pattern] 빌더 패턴(Builder Pattern)에 대해서, @Builder - 컴도리돌이

객체를 생성할 때, 보통 다음과 같이 코드를 작성할 것입니다.  public void builderPattern() { Car car = new Car(); ...} 하지만 객체를 생성할 때는, 빈 깡통으로 사용하기보다는 그 객체의 고유한 값을 갖

comdolidol-i.tistory.com

 

이때 빌더 패턴이 등장합니다. 빌더 패턴은 객체 생성 시 각 매개변수를 명확하게 지정할 수 있게 도와줘요. 예를 들어, "servingSize는 240, servings는 8, 칼로리는 100" 이런 식으로 말이죠. 다음은 빌더 패턴을 구현한 코드입니다. 롬복 라이브러리를 사용해서, @Builder 어노테이션을 사용해 쉽게 빌더 패턴을 다음과 같이 구현할 수 있어요 👍

 

import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;
}
NutritionFacts nutritionFacts = NutritionFacts.builder()
                                                .servingSize(240)
                                                .servings(8)
                                                .calories(100)
                                                .sodium(35)
                                                .carbohydrate(27)
                                                .build();

 

이렇게 하면 매개변수의 의미가 명확해지고, 순서도 헷갈릴 일이 없어지게 되죠. 사실 빌더 패턴은 "좋은 안내판"과 같은 역할을 합니다. 복잡한 길을 헤매지 않고 목적지에 정확히 도달할 수 있도록 도와주니까요. 생성자와 빌더 패턴을 비교해 보면, 생성자는 사용이 간단하고, 작은 매개변수 집합을 다룰 때는 여전히 좋은 선택이에요. 하지만 매개변수가 많아질수록 빌더 패턴의 장점이 빛을 발하게 됩니다. 특히 매개변수가 많고 선택적일 때 빌더는 정말 유용해집니다. 


클라이언트에서 요청받은 데이터를 처리하는 과정에서 검색 DTO를 생성하는 로직이 있는데, 이 dto를 생성할 때 사용하는 매개변수 중 하나를 수정해야 했던 일이 있었어요. 그런데 이 매개변수가 도대체 어떤 역할을 하는지 헷갈리는 바람에 시간을 엄청나게 잡아먹게 된 기억이 있네요. 시간이 지나고 해당 코드들이랑 친해져서 어떤 역할인지 바로바로 알 수 있지만 이번 챕터를 스터디하면서 그때 일이 기억나네요 😭

 

이런 경험, 누구나 한 번쯤은 해봤지 않나요? 많은 매개변수로 인해 코드가 복잡해지고, 특정 값이 무엇을 의미하는지 파악하기 어려운 경우 말이죠. 그래서 이번 기회에 저도 해당 챕터를 스터디해 봤으니, 시간 날 때 한번 도입해 보려고요. 😎


 

 

Effective Java | Item 2. 생성자에 매개변수가 많다면 빌더를 고려하라.

Effective Java 3/E 판을 읽고 정리한 기록입니다. "생성자에 매개변수가 많다면, 빌더를 고려하라"는 것은 자바에서 객체를 생성할 때, 매개변수가 많은 경우, 가독성이 떨어지고 실수를 범하기 쉬워

yujin-17.tistory.com