CS/디자인패턴

[Design Pattern] Builder Pattern(빌더 패턴)

2024. 2. 7. 17:35
목차
  1. Builder Parttern이란?
  2. Builder Pattern을 쓰는 이유 (== 기존 개발 형태에 대한 문제점)?
  3. 1. 점층적 생성자 패턴
  4. 2. 자바 빈즈 패턴
  5. Builder Pattern(빌더 패턴) 구현 방법
  6. Builder Pattern의 장단점
  7. Builder 어노테이션(@Builder)

 

Builder Parttern이란?

Builder Pattern은 디자인 패턴의 종류(생성, 구조, 행동) 중 생성 디자인 패턴에 속한다.

객체를 만드는 방법이 여러 가지 일때, 즉 옵션이 많은 객체를 만들어야할 때 사용함

 

Builder Pattern을 쓰는 이유 (== 기존 개발 형태에 대한 문제점)?

만일 집(아파트가 아닌 독립 주택)이라는 클래스가 있다고 하자. 

해당 집에는 지붕, 방, 창문, 화장실, 마당, 발코니 등 여러 요소가 있고 할때 이를 클래스로 구현하면 다음과 같다.

 

public class House {
  private int rooms;
  private int toilets;
  private int windows;
  private int floors;
  private boolean hasBalcony;
  private boolean hasBackyard;
}

 

이 클래스의 객체를 생성하기 위해서는 기존에는 두가지 방법으로 구현했다.

1. 점층적 생성자 패턴

2. 자바 빈즈 패턴

 

1. 점층적 생성자 패턴

이름 그대로 여러 개의 필드가 있을 때 점층적으로 생성자를 만들어두는 방법이다.

점층적 생성자 패턴은 다음과 같다.

public class House {
  private int rooms;
  private int toilets;
  private int windows;
  private int floors;
  private boolean hasBalcony;
  private boolean hasBackyard;

  public House(int rooms, int toilets, int windows) {
    this.rooms = rooms;
    this.rooms = toilets;
    this.windows = windows;
  }

  public House(int rooms, int toilets, int windows, int floors) {
    this.rooms = rooms;
    this.rooms = toilets;
    this.windows = windows;
    this.floors = floors;
  }
  public House(int rooms, int toilets, int windows, int floors, boolean hasBalcony) {
    this.rooms = rooms;
    this.rooms = toilets;
    this.windows = windows;
    this.floors = floors;
    this.hasBalcony = hasBalcony;
  }

  public House(int rooms, int toilets, int windows, int floors, boolean hasBalcony, boolean hasBackyard) {
    this.rooms = rooms;
    this.rooms = toilets;
    this.windows = windows;
    this.floors = floors;
    this.hasBalcony = hasBalcony;
    this.hasBackyard = hasBackyard;
  }
}

 

이런 점층적 생성자 패턴을 이용해 House 클래스를 인스턴스화 해보자.

 

  public static void main(String[] args) {
    House myhouse = new House(3, 2, 3, 2, false, false);
  }

 

필드(프로퍼티)가 많을 때 가독성이 떨어진다. 앞에 나와있는 3이 무슨 필드였고 뒤에 나오는 false들이 무슨 필드를 뜻하는지 외우지 않는 이상 알기가 어렵다.

 

또한 House 클래스에 필드를 추가할때 별도로 생성자를 만들거나 수정해줘야 null 값이 없는 완전한 객체를 만들 수 있다.

 

2. 자바 빈즈 패턴

이 패턴은 앞서 점층적 생성자 패턴과 달리 매개변수가 없는 생성자로만 객체를 만든 후, setter 메서드를 호출해 원하는 매개변수의 값을 설정하는 방법이다.

 

public class House {
  private int rooms;
  private int toilets;
  private int windows;
  private int floors;
  private boolean hasBalcony;
  private boolean hasBackyard;

  public House() {}

  public void setRooms(int rooms) {
    this.rooms = rooms;
  }

  public void setToilets(int toilets) {
    this.toilets = toilets;
  }

  public void setWindows(int windows) {
    this.windows = windows;
  }

  public void setFloors(int floors) {
    this.floors = floors;
  }

  public void setHasBalcony(boolean hasBalcony) {
    this.hasBalcony = hasBalcony;
  }

  public void setHasBackyard(boolean hasBackyard) {
    this.hasBackyard = hasBackyard;
  }
  public static void main(String[] args) {
    House myhouse = new House();

    myhouse.setRooms(3);
    myhouse.setToilets(2);
    myhouse.setWindows(3);
    myhouse.setFloors(2);
    myhouse.setHasBalcony(false);
    myhouse.setHasBackyard(false);
  }
}

 

자바 빈즈 패턴을 사용하면 이전 점층적 생성자 패턴보다는 어떤 필드 값에 어떤 값을 가지는지 조금 명확해졌지만 setter 메서드로 인해 불변성이 깨진다는 것이 단점이다.

 

Builder Pattern(빌더 패턴) 구현 방법

빌더 패턴은 Builder 클래스를 별도로 만들어주면 된다.

 

public class House {
  private int rooms;
  private int toilets;
  private int windows;
  private int floors;
  private boolean hasBalcony;
  private boolean hasBackyard;

  public static class HouseBuilder {
    private House house;

    public HouseBuilder() {
      this.house = new House();
    }

    public HouseBuilder rooms(int rooms) {
      this.house.rooms = rooms;
      return this;
    }
    public HouseBuilder toilets(int toilets) {
      this.house.toilets = toilets;
      return this;
    }
    public HouseBuilder windows(int windows) {
      this.house.windows = windows;
      return this;
    }

    public HouseBuilder floors(int floors) {
      this.house.floors = floors;
      return this;
    }
    public HouseBuilder hasBalcony(boolean hasBalcony) {
      this.house.hasBalcony = hasBalcony;
      return this;
    }
    public HouseBuilder hasBackyard(boolean hasBackyard) {
      this.house.hasBackyard = hasBackyard;
      return this;
    }

    public House build() {
      return this.house;
    }
  }

  public static void main(String[] args) {
    House myhouse = new HouseBuilder()
        .rooms(3)
        .toilets(2)
        .windows(3)
        .floors(2)
        .hasBalcony(false)
        .hasBackyard(false)
        .build();
  }
}

 

우리는 이 빌더 패턴으로 점층적 생성자 패턴과 같이 불변성을 보장할 수 있고, 자바 빈즈 패턴처럼 어떤 필드에 어떤 값을 가지는지 가독성을 높일 수 있다. 그리고 추가적으로 체이닝기법을 사용해서 연속적으로 쓸 수 있다.

 

물론 빌더 패턴이 최선의 방법이라고 찬양해서는 안된다. 어느 것이나 일장 일단이 있으니!

(TMI: 사실 나는 팀프로젝트 멘토님께 따로 조언 듣기 전에는 DTO객체에서도 setter 메서드를 절대적으로 지양했었다. 불변성이 제일 중요할 것이라고 생각 했기 때문에.. 그러나 어느정도 현업에서 수정이 잦은 필드에만 @Setter를 쓰기도 하고 동시에 여러개의 필드를 수정해야할 경우 setter 메서드를 생성하는 것이 더 좋을 때도 있다는 조언을 듣기도 했었다.. 알다가도 모를 개발의 규칙.. ㅎ..ㅎ)

 

Builder Pattern의 장단점

빌더 패턴의 장단점은 다음과 같다.

장점

  • 코드를 더 깔끔하고 관리하기 쉽게 만드는데 도움이 됨. 
  • 어느 필드에 어느 값을 넣는지 명확하게 확인 할 수 있음.
  • setter로 값을 지정하는 것이 아니라 불변성 보장함.
  • 객체를 생성할 때 한번에 생성하므로 객체 일관성이 깨지지 않음.
  • 새 기능과 설정 방법만 추가하면 되고 코드의 다른 부분을 변경하거나 수정할 필요가 없음.

단점

  • 객체를 생성하기 위해 빌더 객체를 추가로 생성해야 하므로 오버헤드가 발생할 수 있음.
  • 일부 필드의 값을 안넣어도 필드가 null로 들어가면서 객체가 생성가능함 ( -> Builder 클래스를 만들 때 필수적인 필드값을 넣어야 생성하는 패턴으로 어느정도 해결이 되긴 된다.)

Builder 어노테이션(@Builder)

사실 스프링에서 lombok을 통해 이 빌더 패턴을 쉽게 이용할 수 있다.

@Builder
public class House {
  private int rooms;
  private int toilets;
  private int windows;
  private int floors;
  private boolean hasBalcony;
  private boolean hasBackyard;

  public static void main(String[] args) {
    House myhouse = new House.builder()
        .rooms(3)
        .toilets(2)
        .windows(3)
        .floors(2)
        .hasBalcony(false)
        .hasBackyard(false)
        .build();
  }
}

 

이렇게 클래스 위에 Builder  어노테이션을 사용해도 되고 특정 필드만 빌더패턴으로 구현하고 싶다면 생성자를 따로 만들어 놓고 그 위에만 Builder 어노테이션을 사용하면 된다.

 

 

참조 : https://johngrib.github.io/wiki/pattern/builder/ 

반응형

'CS > 디자인패턴' 카테고리의 다른 글

[Design Pattern] Strategy Pattern(전략 패턴)  (0) 2024.06.02
[Design Pattern] Factory Pattern(팩토리 패턴)  (0) 2024.06.01
[Design Pattern] Singleton Pattern(싱글톤 패턴)  (0) 2024.05.31
[Design Pattern] Observer pattern(옵저버 패턴)  (0) 2024.01.24
[Design Pattern] 디자인 패턴이란?  (0) 2024.01.23
  1. Builder Parttern이란?
  2. Builder Pattern을 쓰는 이유 (== 기존 개발 형태에 대한 문제점)?
  3. 1. 점층적 생성자 패턴
  4. 2. 자바 빈즈 패턴
  5. Builder Pattern(빌더 패턴) 구현 방법
  6. Builder Pattern의 장단점
  7. Builder 어노테이션(@Builder)
'CS/디자인패턴' 카테고리의 다른 글
  • [Design Pattern] Factory Pattern(팩토리 패턴)
  • [Design Pattern] Singleton Pattern(싱글톤 패턴)
  • [Design Pattern] Observer pattern(옵저버 패턴)
  • [Design Pattern] 디자인 패턴이란?
three von
three von
어려워 보이는 프로그래밍 언어를 쉽게 정복하는 블로그
반응형
three von
LangEASY : 프로그래밍 언어를 쉽게 정복하는 공간
three von
전체
오늘
어제
  • 분류 전체보기 (89)
    • BackEnd (5)
    • JAVA (5)
      • 기초개념 (5)
    • 자료구조 & 알고리즘 (7)
      • 기초수학 (0)
      • 선형 자료구조 (4)
      • 비선형 자료구조 (1)
      • 알고리즘 (1)
    • CS (18)
      • 컴퓨터구조 (0)
      • 운영체제 (3)
      • 시스템 소프트웨어 (0)
      • 네트워크 (4)
      • 디자인패턴 (10)
    • 데이터베이스 (4)
    • Spring (4)
    • Project (2)
      • 팀프로젝트 (1)
      • 토이프로젝트 (1)
    • 회고 (0)
    • Git&Github (8)
    • IntelliJ (5)
    • 코테 (16)
      • 프로그래머스 (10)
      • 백준 (6)
    • BookStudy (12)
      • 스프링 부트 핵심 가이드 (12)
    • C++ (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자바 자바해시맵
  • windowcmd창
  • 코테
  • vi/vim
  • 명령어변환
  • 백엔드 스쿨
  • 백엔드스쿨
  • 윈도우에서 리눅스 명령어
  • 백엔드
  • spring
  • 리눅스 명령어 윈도우 cmd창에서 가능
  • 제로베이스
  • 깃 이슈관리
  • 백엔드공부
  • java heap 자료구조
  • 자바 자료구조 힙
  • Java
  • InteliJ에서 gitbash사용
  • github이슈관리
  • githubTest
  • vi/vim에디터사용
  • 자바 선형자료구조
  • 제로베이스백엔드스쿨
  • github
  • 제로베이스백엔드스쿨미니과제
  • IntelliJ 자동화
  • LiveTemplate사용
  • 인텔리제이에서 gitbash로 vi vim 에디터 사용하는법
  • 개발자
  • heap 자료구조

최근 댓글

최근 글

hELLO · Designed By 정상우.
three von
[Design Pattern] Builder Pattern(빌더 패턴)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.