본문 바로가기
Programming/Java

[Java] Builder pattern -이해 및 사용방법

by wonduk 2023. 8. 31.
728x90

디자인패턴이란?

소프트웨어 디자인에서 반복적으로 발생하는 문제에 대한 재사용을 할 수 있는 표준화 된 방법을 의미합니다.

적용시에 코드의 유연성,재사용성, 확장성 등의 장점이 있고 유지보수가 쉬워지는 장점이 있습니다.

 

Builder 패턴이란?

디자인 패턴중 생성패턴의 한 종류입니다.

 

builder 패턴이 생겨난 이유 - 

  • 1.클래스가 많은 매개변수를 가지고 객체를 생성할 때 매개변수 순서를 기억하기 어려움 (실수하기 쉬워짐)
  • 2.객체 생성시에 일부 매개변수만 사용해서 생성자처리를 할려면 생성자 오버로딩을 통해서 생성하게 되는데 매개변수가 많아질 경우 모든 경우에 수에 따른 오버로딩을 해야해서 생성자수가 너무 많아짐 (많은 매개변수에서의 생성자 최소화)
  • 3.객체의 불변성을 유지하면서 객체를 생성할려면 필드값을 변경하지 않고 생성자나 메서드를 생성하는 방법이 필요(객체 내부상태가 변하지 않으면서 복잡한 개체를 생성하고 싶음)

builder패턴의 장점

  • 1.객체 생성코드가 명확하고 가독성이 좋아짐
  • 2.매개변수의 순서나 조합을 자유롭게 사용해서 객체생성이 가능함
  • 불필요한 생성자를 만들지 않을 수 있음

 

Builder패턴을 사용하지 않은 코드

public class User {
    private String id;
    private String pw;

    public User(String id, String pw) {
        this.id = id;
        this.pw = pw;
    }

    // Getter, Setter 생략
}

// 사용 예시
User user = new User("myUsername", "myPassword");

 

 

Builder패턴을 사용한 코드

// Builder 패턴을 사용한 예시
public class User {
    private String id;
    private String pw;

    private User(Builder builder) {
        this.id = builder.id;
        this.pw = builder.pw;
    }

    public static class Builder {
        private String id;
        private String pw;

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

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

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

// 사용 예시
User user = new User.Builder()
                    .id("myUsername")
                    .pw("myPassword")
                    .build();

 

위의 코드는 간단하게 매개변수가 2개로 사용한다고 하였을 때 까먹을 일 없이

id와 pw의 위치를 제대로 적을 수 있다고 생각합니다.

사용예시에서 처럼 "."을 사용해서 Builder().build(); 사이에 적어주면 됩니다.

 

매개변수가 여러개이고 모든 매개변수를 사용하는게 아닌 일부 매개변수만도 사용해야하는 경우 사용하기 좋습니다.

아래에는 매개변수가 많은 일기장을 만든다고 했을 때 예시입니다.

변수는 제목,날씨,내용, 날짜, 기분 으로 적는다고 가정하겠습니다.

 

Builder패턴없이 생성자로 만들어서 작성하는 경우

import java.util.Date;

public class Diary {
    private String title;
    private String weather;
    private String content;
    private Date date;
    private String mood;

    public Diary(String title, String weather, String content, Date date, String mood) {
        this.title = title;
        this.weather = weather;
        this.content = content;
        this.date = date;
        this.mood = mood;
    }

    // 생성자 오버로딩으로 모든 경우의 수 추가
    public Diary(String title, String weather, String content, Date date) {
        this(title, weather, content, date, null);
    }

    public Diary(String title, String weather, String content, String mood) {
        this(title, weather, content, null, mood);
    }

    public Diary(String title, String weather, String content) {
        this(title, weather, content, null, null);
    }

    // Getter, Setter 등 생략
}

// 사용 예시
Diary diary1 = new Diary("My Day", "Sunny", "Today was a wonderful day!", new Date(), "Happy");
Diary diary2 = new Diary("Rainy Day", "Rainy", "Spent the day indoors.");
Diary diary3 = new Diary("Mixed Weather", "Cloudy", "Had a mix of sunshine and rain.", "Content");
Diary diary4 = new Diary("Lazy Day", "Sunny", "Just relaxed at home.");

다음과 같이 사용을 할 때 사용 예시에서 코드의 가독성이 떨어지고,  개발자가 코드를 작성할 때 순서를 지켜서 기억해서 작성해야함으로 불편함이 있습니다.

 

Builder 패턴을 사용한 경우

import lombok.Builder;
import java.util.Date;

@Builder
public class Diary {
    private String title;
    private String weather;
    private String content;
    private Date date;
    private String mood;
}

// 사용 예시
Diary diary = Diary.builder()
                    .title("My Day")
                    .weather("Sunny")
                    .content("Today was a wonderful day!")
                    .date(new Date())
                    .mood("Happy")
                    .build();

빌더패턴을 사용한 경우 어떤 변수명에 값이 어떻게 들어가는지 더욱 더 명확해져서 코드의 가독성이 좋아지는 장점이 있습니다.

 

 

 

 

 

 

 

 

 

 

728x90