인프런 커뮤니티 질문&답변

eomukeomukeomuk님의 프로필 이미지

작성한 질문수

Practical Testing: 실용적인 테스트 가이드

Business Layer 테스트 (1)

빌더 사용에 대해 질문드립니다!

해결된 질문

23.06.21 18:11 작성

·

904

·

수정됨

4

안녕하세요 선생님. 빌더를 사용하시는 것을 보고 흥미가 동해 질문남깁니다!

선생님께서는 예제의 경우 대부분 생성자를 private으로 막아두고 빌더를 통해서만 객체를 생성하시는 것 같습니다.

저는 필드 개수가 많아도 public 생성자로 열어두는 편인데, 그 이유는

  • 어떤 인자를 전달해야할지 인텔리제이의 힌트로 알아채기도 편하고

  • 필드가 null 일 수도 있는 경우 객체를 생성할 때 명시적으로 null 이 보이는게 낫다

라고 생각해서입니다.

null을 명시적으로 인자로 전달하는 것이 불편하다면 텔레스코핑을 통해 생성자를 조금 더 만들어두기도 합니다 :)

물론 빌더 패턴을 사용하면 이런 코드들이 전부(?) 사라지기는 하지만, 이 외에 빌더로 객체 생성을 강제하는 것에 대한 장점이 있는지 궁금합니다! 또, 선생님만의 빌더랑 생성자 선택 기준이 따로 있을까요? 마지막으로 실무에서도 자주 사용하시는지 궁금합니다.

좋은 강의 감사드립니다 :)

답변 2

7

박우빈님의 프로필 이미지
박우빈
지식공유자

2023. 06. 24. 11:08

안녕하세요, haero77님! :)

좋은 질문이네요 👍

저는 주로 다음과 같은 형태를 많이 사용합니다.

  • 객체에는 보신 바와 같이 생성자 대신 Builder를 열어둡니다.

  • 프로덕션 코드에서는 생성자나 빌더 보다는 행간의 의미와 생성 의도를 드러낼 수 있는 정적 팩토리 메서드를 주로 사용합니다.

    • 정적 팩토리 메서드 내에서는 빌더를 사용하여 객체를 생성합니다.

    • 객체 생성 전, 필요한 validation을 진행합니다. (공통의 validation이라면 생성자 내에서 진행합니다.)

    • 적절한 메서드명과 파라미터를 두어 팩토리 메서드의 의도를 드러냅니다. (특별한 의미가 없다면 of()를 주로 사용합니다.)

  • 테스트 코드에서는 열어둔 빌더를 사용합니다. 단, 빌더를 그대로 사용할 경우 그 길이로 인해 테스트 코드의 가독성을 해칠 수 있으므로 해당 테스트 메서드에 적합한 파라미터만을 드러내는 private 메서드로 추상화하여 사용합니다. (강의 내용)

제 나름의 규칙을 정리하면 위와 같을텐데, 이를 떠나서 빌더를 사용하는 가장 큰 이유는 바로 필드 매핑입니다.

String name = "이름";
String text = "비고";

// 생성자
new Something(name, text);

// 실수할 여지
new Something(text, name);

// 명시적인 빌더
Something.builder()
    .name(name)
    .text(text)
    .build();

// 정적 팩토리 메서드
Something.of(name, text);

단순한 예시지만, 만약 문자열 같이 동일한 타입의 파라미터가 많아질 경우 일반 생성자로는 실수가 생길 확률이 높습니다.
빌더 패턴을 사용하면 어떤 필드를 어떤 순서로 넣어야 하는지를 신경쓰지 않아도 되고, 명시적이기 때문에 다소 실수할 확률이 적다고 볼 수 있습니다.
다만, 빌더의 경우 코드 양이 많아진다는 점, 그리고 위에서 언급한 정적 팩토리 메서드를 사용하는 경우 생성자를 사용하는 방법과 동일한 우려가 있을 수 있긴 합니다.
정적 팩토리 메서드의 경우 생성자와 비슷하다고 볼 수 있지만, 상황에 따라 파라미터의 수를 제한하고, 이름을 지어 의도를 드러낼 수 있다는 점이 가장 큰 장점이죠.

(단, 코틀린에서는 생성자 자체에서 필드 이름 명시, 기본값 지정 등의 편의 기능을 제공해주고 있기 때문에 빌더가 필요하지 않고, 생성자만으로도 충분합니다. 😅)

위와 같은 이유로 저는 빌더와 정적 팩토리 메서드 중에 골라서 사용하고 있지만, 간단한 객체의 경우는 생성자만 사용해도 큰 무리는 없으니 상황에 따라 잘 골라서 사용하시면 좋을 것 같습니다. :)

부연 설명이 조금 많았는데, 의도가 잘 전달되었기를 바랍니다. ㅎㅎ
감사합니다! :)

eomukeomukeomuk님의 프로필 이미지

2023. 06. 24. 14:20

답변 감사합니다 :)

빌더랑 생성자를 번갈아 사용해보면서, 트레이드 오프를 고려하면 이 때는 빌더가 낫겠구나처럼 저만의 기준을 세워나가보도록 하겠습니다!

0

인프런 AI 인턴님의 프로필 이미지

2023. 06. 23. 18:16

안녕하세요, 인프런 AI 인턴이에요.

빌더 패턴의 경우, 객체 생성 시 필드가 많을 경우 생성자 인자의 개수가 많아져 가독성과 유지보수성이 낮아질 수 있습니다. 빌더 패턴을 사용하면 객체 생성 시, 인자의 순서나 타입을 신경쓰지 않아도 되므로 코드 작성이 보다 간단해질 수 있습니다. 게다가 빌더 패턴을 사용하면 필드 값의 무결성을 보장할 수도 있어 프로그램의 안정성 측면에서 더욱 좋다고 할 수 있습니다.

그러나 필드 개수가 적거나 필드 값의 무결성을 보장하지 않아도 되는 경우에는 생성자만으로 객체를 생성하는 것도 괜찮은 방법입니다. 빌더 패턴을 사용하지 않더라도, 생성자 오버로딩을 통해 필요한 생성자를 만들어 사용할 수도 있습니다. 이는 개발자 간 코드 작성 스타일 차이에 따라 다를 수 있습니다.

빌더 패턴과 생성자 중 어떤 것을 선택할지는 상황에 따라 다릅니다. 필드 값의 무결성이 보장되어야 하거나 필드가 많은 경우 빌더 패턴을 선택할 수 있고, 필드 개수가 적거나 무결성을 보장하지 않아도 된다면 생성자를 선택할 수도 있습니다.

실무에서도 빌더 패턴은 자주 사용됩니다. 특히 객체 생성 시 필드가 많은 경우 빌더 패턴을 사용하여 가독성과 유지보수성을 높일 수 있습니다.

도움이 되셨길 바랍니다. 감사합니다.