@LEELEE
dev note
@LEELEE
  • 분류 전체보기 (29)
    • Project (10)
    • Study (19)
      • Java (9)
      • Spring (3)
      • Test (2)
      • DB (2)
      • Infra (1)
      • ETC (2)
      • CS (0)
    • 노트 (0)

인기 글

최근 글

태그

  • 배포자동화
  • AWS
  • 예외처리
  • Leetcode
  • 이펙티브자바
  • was
  • Redis
  • HTTP
  • springboot
  • transaction
  • oracle
  • Java
  • Spring
  • Til
  • DB
  • PostgreSQL
  • junit
  • 객체지향
  • PS
  • test
전체 방문자
오늘
어제
hELLO · Designed By 정상우.
@LEELEE

dev note

Study/Java

자바 빌더 패턴 Java Builder Pattern

2022. 5. 31. 23:55

무한 생성자 오버로드(overload)

이미 생성자 오버로드가 너무 많았고 나도 거기에 하나를 더 추가해야 하는 상황이 있었다.

생성자를 호출할 때 매개변수에 대한 정보를 알 수 없는 점이 너무 불편했고 코드도 쓸데없이 너무 길어졌다.

// 예시
public class NutritionFacts {
	private final int servingSize;
	private final int servings;
	private final int calories;
	private final int fat;
    
	public NutritionFacts() {
		this(0)
	}
 
	public NutritionFacts(int servingSize) {
		this(servingSize, 0)
	}
    
	public NutritionFacts(int servingSize, int servings) {
		this(servingSize, servings, 0)
	}
    
	public NutritionFacts(int servingSize, int servings, int calories) {
		this(servingSize, servings, calories, 0)
	}
    
	public NutritionFacts(int servingSize, int servings, int calories, int fat) {
		this.servingSize = servingSize;
		this.servings = servings;
		this.calories = calories;
		this.fat = fat;
	}
}
// 실제로는 필드가 이거의 세 배는 넘었던 것 같다

이를 점층적 생성자 패턴(Telescoping Constructor Pattern)이라고 하는데 매개변수가 많을 때는 적합하지 않다고 한다.

더 좋은 방법 없나 찾아보다가 그 때 처음 빌더 패턴을 알게 되었다.

 

 

Builder Pattern 

객체를 직접 만드는 대신 빌더라는 애한테 객체를 만들어달라고 하는 패턴이다.

 

객체를 직접 만드는 방법

NutritionFacts pepsi = new NutritionFacts(1, 1, 120);

 

대신

 

빌더라는 애한테 객체를 만들어 달라고 함

NutritionFacts pepsi = new NutritionFacts.Builder(1, 1)

.calories(120).fat(20).build();

 

빌더 패턴의 원리

빌더는 생성할 클래스 내부에 static 멤버 클래스로 만듦

각각의 setter(public Builder calories, public Builder fat .. )로 매개변수 설정

build라는 메서드는 만들어 달라고 한 객체를 생성하고 넘겨줌

// 예시 - 이펙티브 자바
public class NutritionFacts {
	private final int servingSize;
	private final int servings;
	private final int calories;
	private final int fat;

	public static class Builder {
		// 필수 매개변수
		private final int servingSize;
		private final int servings;

		// 선택 매개변수 - 기본값으로 초기화한다.
		private int calories      = 0;
		private int fat           = 0;

		public Builder(int servingSize, int servings) {
			this.servingSize = servingSize;
			this.servings    = servings;
		}

		public Builder calories(int val)
		{ calories = val;      return this; }
		public Builder fat(int val)
		{ fat = val;           return this; }

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

	private NutritionFacts(Builder builder) {
		servingSize  = builder.servingSize;
		servings     = builder.servings;
		calories     = builder.calories;
		fat          = builder.fat;
    }
}

 

빌더 패턴의 장점

  • setter명을 통해 매개변수 대한 정보를 알 수 있음
  • 직접 생성 시 매개변수 순서 맞춰서 적는 짓 안 해도 됨
  • 클래스의 내부 구조 몰라도 객체 생성 가능
  • 매개변수 많을 때 너무 편하다

 

아래는 개발하면서 봤던 Java Slack API의 빌더 패턴

import com.slack.api.methods.MethodsClient;
import com.slack.api.methods.request.chat.ChatPostMessageRequest;
import com.slack.api.methods.response.chat.ChatPostMessageResponse;

public class SlackExample {
// Load an env variable
// If the token is a bot token, it starts with `xoxb-` while if it's a user token, it starts with `xoxp-`
String token = System.getenv("SLACK_TOKEN");

// Initialize an API Methods client with the given token
MethodsClient methods = slack.methods(token);

// Build a request object
ChatPostMessageRequest request = ChatPostMessageRequest.builder()
  .channel("#random") // Use a channel ID `C1234567` is preferrable
  .text(":wave: Hi from a bot written in Java!")
  .build();

// Get a response as a Java object
ChatPostMessageResponse response = methods.chatPostMessage(request);
}

// Java Slack API 코드

 

빌더 패턴의 단점

  • 마찬가지로 매개변수가 너~무 많아지면 코드도 너~무 길어진다

 

 

Lombok의 @Builder

롬복의 빌더 어노테이션을 적절히 사용하면 빌더 패턴의 단점을 보완하여 코드를 줄일 수 있다. 

 

 

 

 

저작자표시

'Study > Java' 카테고리의 다른 글

[Java] 제네릭  (0) 2023.02.01
JVM 명세 - Run-Time Data Areas  (0) 2022.06.25
자바로 간단한 http 웹 서버 구현  (0) 2022.06.11
간단한 자바 TCP 통신 구현  (0) 2022.06.02
[JAVA] 메인메소드 public static void main(String[] args)에 대해  (0) 2018.09.16
    'Study/Java' 카테고리의 다른 글
    • JVM 명세 - Run-Time Data Areas
    • 자바로 간단한 http 웹 서버 구현
    • 간단한 자바 TCP 통신 구현
    • [JAVA] 메인메소드 public static void main(String[] args)에 대해
    @LEELEE
    @LEELEE

    티스토리툴바