디자인 패턴

자바(JAVA) - 빌더(Builder) 패턴

Hyeongjun_Ham 2023. 10. 18. 16:18

1. 의도

복잡한 객체를 생성하는 클래스와 표현하는 클래스를 분리하여, 동일한 절차에서도 서로 다른 표현을 생성하는 방법을 제공한다.

 

2. 용도

매개변수가 많은 객체를 안전하게 생성해야 할 때 사용하면 좋다.

 

3. UML

4. 구현

getter, setter, toString은 생략하자.

 

  • TourPlan
public class TourPlan {

    private String title;
    private LocalDate startDate;
    private LocalDate endDate;
    private String startPlace;
    private String endPlace;
    private List<Cyclist> cyclists;

    public TourPlan() {
    }
}
  • Cyclist
public class Cyclist {
    private String name;

    private String bikeName;

    public Cyclist(String name, String bikeName) {
        this.name = name;
        this.bikeName = bikeName;
    }
}
  • Client
public class Client {
    public static void main(String[] args) {
        TourPlanDirector tourPlanDirector = new TourPlanDirector(new DefaultTourBuilder());

        TourPlan tourPlan = tourPlanDirector.busanTrip();

        System.out.println(tourPlan.toString());
    }
}
  • Director
public class TourPlanDirector {
    private TourPlanBuilder tourPlanBuilder;
    
    public TourPlanDirector(TourPlanBuilder tourPlanBuilder) {
        this.tourPlanBuilder = tourPlanBuilder;
    }

    public TourPlan busanTrip() {
        return tourPlanBuilder
                .title("부산 종주")
                .startDate(LocalDate.parse("2023-10-21"))
                .endDate(LocalDate.parse("2023-10-24"))
                .startPlace("하남")
                .endPlace("부산")
                .addCyclist("나", "Merida")
                .addCyclist("동료", "Look")
                .build();
    }
}
  • Builder(interface)
public interface TourPlanBuilder {
    TourPlanBuilder title(String title);

    TourPlanBuilder startDate(LocalDate startDate);

    TourPlanBuilder endDate(LocalDate endDate);

    TourPlanBuilder startPlace(String startPlace);

    TourPlanBuilder endPlace(String endPlace);

    TourPlanBuilder addCyclist(String name, String bikeName);

    TourPlan build();
}
  • Builder 구현
public class DefaultTourBuilder implements TourPlanBuilder {

    private final TourPlan tourPlan = new TourPlan();

    public DefaultTourBuilder() {
    }

    @Override
    public TourPlanBuilder title(String title) {
        this.tourPlan.setTitle(title);
        return this;
    }

    @Override
    public TourPlanBuilder startDate(LocalDate startDate) {
        this.tourPlan.setStartDate(startDate);
        return this;
    }

    @Override
    public TourPlanBuilder endDate(LocalDate endDate) {
        this.tourPlan.setEndDate(endDate);
        return this;
    }

    @Override
    public TourPlanBuilder startPlace(String startPlace) {
        this.tourPlan.setStartPlace(startPlace);
        return this;
    }

    @Override
    public TourPlanBuilder endPlace(String endPlace) {
        this.tourPlan.setEndPlace(endPlace);
        return this;
    }

    @Override
    public TourPlanBuilder addCyclist(String name, String bikeName) {
        if (this.tourPlan.getCyclists() == null) {
            this.tourPlan.setCyclists(new ArrayList<>());
        }
        this.tourPlan.getCyclists().add(new Cyclist(name, bikeName));
        return this;
    }

    @Override
    public TourPlan build() {
        return tourPlan;
    }
}

5. 패턴의 장단점

  • 장점
    • 쓰기 쉽고, 읽기 쉽다.
    • 계층적으로 설계된 클래스와 함께 쓰기 좋다.
    • 매개변수에 따라 다른 객체를 만들 수 있다.
  • 단점
    • 객체를 만드려면 빌더부터 만들어야 한다.(Lombok으로 해결 가능)
    • 코드가 장황하여 매개변수가 4개 이상은 되어야 값어치를 한다.

 

출처 :

https://refactoring.guru/design-patterns/builder

 

Builder

Say you have a constructor with ten optional parameters. Calling such a beast is very inconvenient; therefore, you overload the constructor and create several shorter versions with fewer parameters. These constructors still refer to the main one, passing s

refactoring.guru