[Java] Builder pattern (Lombok)

κΉ€μ •λ―ΌΒ·2024λ…„ 4μ›” 2일
3
post-thumbnail

μ½”ν‹€λ¦°μ—μ„œλŠ” ν•„μš” μ—†λ˜ Builder νŒ¨ν„΄μ΄ μžλ°”λ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ ν•„μš”ν•˜λ‹€κ³  생각이 λ“€μ—ˆλ‹€.

ν•œ λΈ”λ‘œκ·Έμ—μ„œ Builder νŒ¨ν„΄μ— λŒ€ν•΄μ„œ λΉŒλ” νŒ¨ν„΄μ„ ꡉμž₯히 잘 닀루어 μ„€λͺ…을 ν•΄μ£Όμ–΄ μ΄ν•΄ν•˜κΈ° 쉽고 μ •λ¦¬ν•˜κ³  μ΄ν•΄ν•˜λŠ” κ²ƒμœΌλ‘œ μ§‘μ€‘ν–ˆλ‹€.

천천히 μ½μœΌλ©΄μ„œ 정리해 보자.

πŸ’‘ λΉŒλ” νŒ¨ν„΄(Builder Pattern) ?

λΉŒλ” νŒ¨ν„΄(Builder Pattern)은 λ³΅μž‘ν•œ 객체의 생성 κ³Όμ •κ³Ό ν‘œν˜„ 방법을 λΆ„λ¦¬ν•˜μ—¬ λ‹€μ–‘ν•œ κ΅¬μ„±μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“œλŠ” 생성 νŒ¨ν„΄μ΄λ‹€. μƒμ„±μžμ— λ“€μ–΄κ°ˆ 맀개 λ³€μˆ˜λ₯Ό λ©”μ„œλ“œλ‘œ ν•˜λ‚˜ν•˜λ‚˜ 받아듀이고 λ§ˆμ§€λ§‰μ— 톡합 λΉŒλ“œν•΄μ„œ 객체λ₯Ό μƒμ„±ν•˜λŠ” 방식이닀.Β 

πŸ’‘ λΉŒλ” νŒ¨ν„΄ 탄생 λ°°κ²½

πŸͺ“ 점측적 μƒμ„±μž νŒ¨ν„΄

점측적 μƒμ„±μž νŒ¨ν„΄(Telescoping Constructor Pattern)은 ν•„μˆ˜ λ§€κ°œλ³€μˆ˜μ™€ ν•¨κ»˜ 선택 λ§€κ°œλ³€μˆ˜λ₯Ό 0개, 1개, 2개 .. λ°›λŠ” ν˜•νƒœλ‘œ, μš°λ¦¬κ°€ λ‹€μ–‘ν•œ λ§€κ°œλ³€μˆ˜λ₯Ό μž…λ ₯λ°›μ•„ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  μ‹Άμ„λ•Œ μ‚¬μš©ν•˜λ˜ μƒμ„±μžλ₯Ό μ˜€λ²„λ‘œλ”© ν•˜λŠ” 방식이닀.

class Hamburger {
    // ν•„μˆ˜ λ§€κ°œλ³€μˆ˜
    private int bun;
    private int patty;

    // 선택 λ§€κ°œλ³€μˆ˜
    private int cheese;
    private int lettuce;
    private int tomato;
    private int bacon;

    public Hamburger(int bun, int patty, int cheese, int lettuce, int tomato, int bacon) {
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
        this.lettuce = lettuce;
        this.tomato = tomato;
        this.bacon = bacon;
    }

    public Hamburger(int bun, int patty, int cheese, int lettuce, int tomato) {
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
        this.lettuce = lettuce;
        this.tomato = tomato;
    }
    

    public Hamburger(int bun, int patty, int cheese, int lettuce) {
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
        this.lettuce = lettuce;
    }

    public Hamburger(int bun, int patty, int cheese) {
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
    }

    ...
}

public static void main(String[] args) {
    // λͺ¨λ“  μž¬λ£Œκ°€ μžˆλŠ” 햄버거
    Hamburger hamburger1 = new Hamburger(2, 1, 2, 4, 6, 8);

    // λΉ΅κ³Ό νŒ¨ν‹° 치즈만 μžˆλŠ” 햄버거
    Hamburger hamburger2 = new Hamburger(2, 1, 1);

    // λΉ΅κ³Ό νŒ¨ν‹° 베이컨만 μžˆλŠ” 햄버거
    Hamburger hamburger3 = new Hamburger(2, 0, 0, 0, 0, 6);
}

νƒ€μž…μ΄ λ‹€μ–‘ν•  수둝 μƒμ„±μž λ©”μ„œλ“œ μˆ˜κ°€ κΈ°ν•˜κΈ‰μˆ˜μ μœΌλ‘œ λŠ˜μ–΄λ‚˜ κ°€λ…μ„±μ΄λ‚˜ μœ μ§€λ³΄μˆ˜ μΈ‘λ©΄μ—μ„œ 쒋지 μ•Šλ‹€.

πŸ”‘ λΉŒλ”(Builder) νŒ¨ν„΄

λΉŒλ” νŒ¨ν„΄μ€ μ΄λŸ¬ν•œ λ¬Έμ œλ“€μ„ ν•΄κ²°ν•˜κΈ° μœ„ν•΄ λ³„λ„μ˜ Builder 클래슀λ₯Ό λ§Œλ“€μ–΄ λ©”μ†Œλ“œλ₯Ό 톡해 step-by-step 으둜 값을 μž…λ ₯받은 후에 μ΅œμ’…μ μœΌλ‘œ build() λ©”μ†Œλ“œλ‘œΒ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ λ¦¬ν„΄ν•˜λŠ” νŒ¨ν„΄μ΄λ‹€.
λΉŒλ” νŒ¨ν„΄ μ‚¬μš©λ²•μ„ μž μ‹œ μ‚΄νŽ΄λ³΄λ©΄, StudentBuilder λΉŒλ” 클래슀의 λ©”μ„œλ“œλ₯Ό 체이닝(Chaining) ν˜•νƒœλ‘œ ν˜ΈμΆœν•¨μœΌλ‘œμ¨ μžμ—°μŠ€λŸ½κ²Œ μΈμŠ€ν„΄μŠ€λ₯Ό κ΅¬μ„±ν•˜κ³  λ§ˆμ§€λ§‰μ—Β build()Β λ©”μ„œλ“œλ₯Ό 톡해 μ΅œμ’…μ μœΌλ‘œ 객체λ₯Ό μƒμ„±ν•˜λ„λ‘ λ˜μ–΄μžˆμŒμ„ λ³Ό 수 μžˆλ‹€.

public static void main(String[] args) {

    // μƒμ„±μž 방식
    Hamburger hamburger = new Hamburger(2, 3, 0, 3, 0, 0);

    // λΉŒλ” 방식
    Hamburger hamburger = new Hamburger.Builder(10)
        .bun(2)
        .patty(3)
        .lettuce(3)
        .build();
}

πŸšͺ λΉŒλ” νŒ¨ν„΄ ꡬ쑰


class Student {
    private int id;
    private String name = "μ•„λ¬΄κ°œ";
    private String grade = "freshman";
    private String phoneNumber = "010-0000-0000";

    public Student(int id, String name, String grade, String phoneNumber) {
        this.id = id;
        this.name = name;
        this.grade = grade;
        this.phoneNumber = phoneNumber;
    }
    
    @Override
    public String toString() {
        return "Student { " +
                "id='" + id + '\'' +
                ", name=" + name +
                ", grade=" + grade +
                ", phoneNumber=" + phoneNumber +
                " }";
    }
}

class StudentBuilder {
    private int id;
    private String name;
    private String grade;
    private String phoneNumber;

    public StudentBuilder id(int id) {
        this.id = id;
        return this;
    }

    public StudentBuilder name(String name) {
        this.name = name;
        return this;
    }

    public StudentBuilder grade(String grade) {
        this.grade = grade;
        return this;
    }

    public StudentBuilder phoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
        return this;
    }
    
    public Student build() {
        return new Student(id, name, grade, phoneNumber); // Student μƒμ„±μž 호좜
    }
}

πŸͺ„ λΉŒλ” 클래슀 μ‹€ν–‰ν•˜κΈ°

public static void main(String[] args) {

    Student student = new StudentBuilder()
                .id(2016120091)
                .name("μž„κΊ½μ •")
                .grade("Senior")
                .phoneNumber("010-5555-5555")
                .build();

    System.out.println(student);
}

πŸ‘€ λΉŒλ” νŒ¨ν„΄(Builder Pattern)의 μž₯점

1. ν•„μš”ν•œ λ°μ΄ν„°λ§Œ μ„€μ •ν•  수 있음

2. μœ μ—°μ„±μ„ 확보할 수 있음

3. 가독성을 높일 수 있음

4. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™”ν•  수 있음

결둠은 객체λ₯Ό μƒμ„±ν•˜λŠ” λŒ€λΆ€λΆ„μ˜ κ²½μš°μ—λŠ” λΉŒλ” νŒ¨ν„΄μ„ μ μš©ν•˜λŠ” 것이 μ’‹λ‹€.

πŸ› οΈ Lombok을 μ΄μš©ν•œ λΉŒλ” νŒ¨ν„΄

@Builder
class Student {
    private int id;
    private String name = "μ•„λ¬΄κ°œ";
    private String grade = "freshman";
    private String phoneNumber = "010-0000-0000";
}

πŸŽ€ Lombok을 μ΄μš©ν•œ λΉŒλ” μ‹€ν–‰ν•˜κΈ°

public static void main(String[] args) {
    Student student = new Student()
                .id(2016120091)
                .name("μž„κΊ½μ •")
                .grade("Senior")
                .phoneNumber("010-5555-5555")
                .build();
}

마무리

코틀린을 μ‚¬μš©ν•  λ•ŒλŠ” λΉŒλ”νŒ¨ν„΄ 없이 μžμ—°μŠ€λŸ½κ²Œ μ‚¬μš©ν–ˆλŠ”λ° μžλ°”λ‘œ ν•˜λ‹ˆ λΆˆνŽΈν•¨μ΄ 생겨 λΉŒλ” νŒ¨ν„΄μ„ μ•Œμ•„λ³΄κ²Œ λ˜μ—ˆλŠ”λ° λΉŒλ” νŒ¨ν„΄μ„ μ΄μš©ν•˜λ©΄ 가독성 및 μœ μ—°μ„±λ„ 확보가 κ°€λŠ₯ν•˜κ³  맀우 도움이 많이 될 것 κ°™λ‹€.

μ§μ ‘μ μœΌλ‘œ λΉŒλ” νŒ¨ν„΄μ˜ μ†ŒμŠ€λ₯Ό μž‘μ„±ν•˜λŠ” 것도 μ’‹μ§€λ§Œ Lombokμ—μ„œ 지원을 ν•΄μ£ΌκΈ° λ•Œλ¬Έμ— μ•žμœΌλ‘œ 보닀 νŽΈν•œ Lombok을 μ΄μš©ν•  생각이닀.


좜처: https://inpa.tistory.com/entry/GOF-πŸ’ -λΉŒλ”Builder-νŒ¨ν„΄-λνŒμ™•-정리 [Inpa Dev πŸ‘¨β€πŸ’»:ν‹°μŠ€ν† λ¦¬]

좜처: https://mangkyu.tistory.com/163 [MangKyu's Diary:ν‹°μŠ€ν† λ¦¬]

좜처: https://refactoring.guru/ko/design-patterns/builder [refactoring.guru]

1개의 λŒ“κΈ€

comment-user-thumbnail
2024λ…„ 4μ›” 4일

λ©‹μ Έμš”

λ‹΅κΈ€ 달기