[디자인 패턴] - Builder
by 볼빵빵오춘기Builder 패턴
복잡한 객체의 생성 과정을 단계별로 나누고, 최종적으로 객체를 조립하여 생성하는 패턴이다.
즉, 객체의 생성 과정과 표현 방법을 분리하여, 동일한 생성 과정에서도 다양한 형태의 객체를 만들 수 있도록 도와준다.
예제 코드
// 1. Product (복잡한 객체)
class Computer {
private String CPU;
private String RAM;
private String storage;
private boolean hasGraphicsCard;
// private 생성자 (객체 직접 생성 불가, Builder를 통해 생성)
private Computer(Builder builder) {
this.CPU = builder.CPU;
this.RAM = builder.RAM;
this.storage = builder.storage;
this.hasGraphicsCard = builder.hasGraphicsCard;
}
@Override
public String toString() {
return "Computer [CPU=" + CPU + ", RAM=" + RAM + ", Storage=" + storage +
", Graphics Card=" + hasGraphicsCard + "]";
}
// 2. Builder (내부 정적 클래스)
public static class Builder {
private String CPU;
private String RAM;
private String storage;
private boolean hasGraphicsCard;
public Builder(String CPU, String RAM) { // 필수 속성 설정
this.CPU = CPU;
this.RAM = RAM;
}
public Builder setStorage(String storage) {
this.storage = storage;
return this;
}
public Builder setGraphicsCard(boolean hasGraphicsCard) {
this.hasGraphicsCard = hasGraphicsCard;
return this;
}
// 최종 객체 생성 메서드
public Computer build() {
return new Computer(this);
}
}
}
// 3. Client 코드 (사용 예제)
public class BuilderExample {
public static void main(String[] args) {
// 필수 속성만 지정
Computer basicComputer = new Computer.Builder("Intel i5", "8GB").build();
System.out.println(basicComputer);
// 추가 옵션 포함
Computer gamingComputer = new Computer.Builder("Intel i9", "32GB")
.setStorage("1TB SSD")
.setGraphicsCard(true)
.build();
System.out.println(gamingComputer);
}
}
Builder 패턴의 장점
가독성 향상
객체 생성 코드가 단계별로 명확하게 구성되어 있어 이해하기 쉽다.
new Computer("Intel i7", "16GB", "512GB SSD", true);
가독성이 낮다.
new Computer.Builder("Intel i7", "16GB").setStorage("512GB SSD").setGraphicsCard(true).build();
가독성이 높다.
객체 생성의 유연성
필요에 따라 선택적인 속성을 설정할 수 있다.
ex) setGraphicsCard()를 호출하지 않으면 기본값(false) 유지한다.
불변 객체(Immutable Object) 생성 가능
private 생성자와 Builder를 사용하면 객체가 불변(Immutable)하게 설계될 수 있다.
생성자의 오버로딩 문제 해결
기존 생성자 방식에서는 다양한 조합을 위해 여러 개의 생성자를 만들어야 하지만, Builder 패턴을 사용하면 불필요한 생성자 오버로딩을 방지할 수 있다.
일관성 유지
클라이언트가 잘못된 객체를 생성하는 실수를 방지할 수 있음.
ex) 필수 속성을 Builder 생성자로 강제할 수 있다.
Builder 패턴의 단점
코드가 복잡해질 수 있다.
단순한 객체 생성에는 필요 없는 코드(Builder 클래스, setter 메서드 등)가 추가된다.
ex) Computer.Builder를 만들어야 하므로, 코드가 다소 길어진다.
객체 생성 비용 증가
Builder 객체를 추가로 생성해야 하므로, 메모리 사용량이 증가할 수 있다.
(But 대부분의 경우 무시할 수 있을 정도로 미미한 단점이다.)
빌더를 변경하면 관련 코드도 수정해야 함
Builder가 변경될 경우, 이를 사용하는 모든 코드에 영향을 미칠 수 있다.
Builder 패턴을 언제 사용할까?
객체의 속성이 많거나 조합이 다양할 때
ex) 컴퓨터, 자동차, 사용자 계정 등 다양한 옵션을 설정할 수 있는 객체.
생성자의 오버로딩이 너무 많을 때
Person(String name), Person(String name, int age), Person(String name, int age, String address), …
→ Builder 패턴으로 개선 가능.
객체가 불변(Immutable)해야 할 때
private final 필드와 함께 사용하면 불변 객체를 쉽게 생성할 수 있다.
객체 생성의 일관성을 유지하고 싶을 때
필수 속성을 강제할 수 있어 불완전한 객체 생성을 방지 가능
정리하자면
- 복잡한 객체의 생성 과정을 명확하고 유연하게 관리할 수 있도록 도와주는 패턴이다.
- 생성자의 오버로딩을 줄이고, 가독성을 높이며, 선택적인 속성을 추가할 수 있도록 해주는 것이 가장 큰 장점이다.
- 단순한 객체에 사용하면 불필요한 코드가 많아질 수 있으므로, 적용할 필요가 없는 경우에는 일반적인 생성자 패턴을 사용할 수도 있다.
∴ 객체가 복잡하고 옵션이 많을 때는 Builder 패턴을 적극적으로 활용하면 좋은 선택이 될 수 있다!
'👩🏻💻 About 프로그래밍 > Spring, Spring boot' 카테고리의 다른 글
[디자인 패턴] - Prototype (0) | 2025.03.25 |
---|---|
[디자인 패턴] - Factory Method (0) | 2025.03.25 |
[디자인 패턴] - Abstract Factory (0) | 2025.03.25 |
[스프링부트 핵심가이드] 개발에 앞서 알면 좋은 기초 지식 - 디자인 패턴 (0) | 2025.02.01 |
[스프링부트 핵심가이드] 개발에 앞서 알면 좋은 기초 지식 - 레이어드 아키텍처 (0) | 2025.02.01 |
블로그의 정보
Hello 춘기's world
볼빵빵오춘기