Unity 내일배움캠프 TIL 1020 | 빌더 패턴 Builder Pattern

cheeseonrose·2023년 10월 20일
0

Unity 내일배움캠프

목록 보기
60/89
post-thumbnail

💡 빌더 패턴 Builder Pattern

☁ 정의

  • 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴
  • 복잡한 객체의 생성 과정과 표현 방법을 분리하여 다양한 구성의 인스턴스를 만드는 생성 패턴
  • 인스턴스를 만드는 절차를 추상화하는 패턴들을 의미
    ex : 싱글톤 패턴, 팩토리 패턴, 추상 팩토리 패턴 등
  • 시스템이 상속(Inheritance)보다 복합(Composite) 방법을 사용하는 방향으로 진화/지향되어 가면서 중요해지고 있는 패턴

🌧 문제점

  • 집 객체를 만들어보자.
    집을 짓기 위해서는 벽과 바닥을 만든 뒤, 문과 창문을 설치하고 지붕도 만들어야 한다.

  • 이때 우리는 보일러나 두꺼비집 등 추가적인 것들을 설치한 현대적인 집을 만들고 싶어졌다! 어떻게 해야 할까?

  • 가장 먼저 떠오르는 해결책은 기초 House 클래스를 확장하고, 매개변수의 모든 조합을 포함하는 자식 클래스들의 집합을 만드는 것이다.
    하지만 이런 방식으로 구현하게 되면 추후 매개변수가 추가 되었을 때(현관 스타일 등) 계층 구조가 복잡해지게 된다!

  • 다른 방식으로는 House 클래스에 House 객체를 제어하는 모든 가능한 매개변수를 포함한 거대한 생성자를 만드는 것이다.
    자식 클래스의 필요성은 사라지지만, 생성자를 호출하는 코드가 매우 길고 복잡해질 것이다!
  • 또한 사용하지 않는 매개변수도 많아지게 된다.

☔ 해결 방안

  • 빌더 패턴을 이용하여 자신의 클래스에서 객체 생성 코드를 추출하여 문제를 해결할 수 있다.
    이 객체 생성 코드는 builders라는 별도의 객체들로 옮겨진다.

  • 객체 생성을 일련의 단계들로 정리하며, 객체를 생성하기 위해서는 builder 객체를 실행하면 된다.
    예를 들어, 문을 건설하기 위해서 buildDoors를 실행하기만 하면 된다!

  • 추가적으로 우리는 똑같은 문을 만들더라도 나무로 만들거나 철로 만들고 싶을 수도 있다.
    이런 경우에 다른 여러 빌더 클래스를 생성하고, 건축 프로세스 내에서 빌더들을 사용하여 다양한 종류의 객체를 생성할 수 있다.


🌞 디렉터(관리자)

  • 제품을 생성하는 데 사용하는 빌더 단계들에 대한 일련의 호출을 디렉터(관리자)라는 별도의 클래스로 추출할 수 있다.

  • 디렉터 클래스는 제작 단계들을 실행하는 순서를 정의하는 반면, 빌더는 이러한 단계들에 대한 구현을 제공한다.

  • 디렉터 클래스는 필수 사항은 아니다.

  • 디렉터 클래스는 클라이언트 코드에서 제품 생성의 세부 정보를 완전히 숨길 수 있다.


🌈 구조

  • 구상 빌더들은 공통 인터페이스를 따르지 않는 제품을 생산할 수 있다.
  • 다른 빌더에 의해 생성된 제품들은 같은 클래스 계층구조 또는 인터페이스에 속할 필요가 없다.
  • 클라이언트는 빌더 객체들 중 하나를 디렉터와 연결해야 한다.
    일반적으로 연결은 디렉터 생성자의 매개변수들을 통해 한 번만 수행되며, 그 후 디렉터는 모든 추가 생성에 해당 빌더 객체들을 사용한다.

🌊 빌더 패턴 네이밍 형식

  • 빌더 패턴의 멤버 설정 메서드 네이밍 방식에는 대표적으로 3가지가 존재한다.
    1. 멤버이름()
    Potato potato = new PotatoBuilder()
    				.name("감자")
                  	.grade("freshmen")
                    .phoneNumber("010-0000-0000")
                    .build();
    1. set멤버이름()
    Potato potato = new PotatoBuilder()
    				.setName("감자")
                  	.setGrade("freshmen")
                    .setPhoneNumber("010-0000-0000")
                    .build();
    1. with멤버이름()
    Potato potato = new PotatoBuilder()
    				.withName("감자")
                  	.withGrade("freshmen")
                    .withPhoneNumber("010-0000-0000")
                    .build();
  • 일반적으로 첫 번째 네이밍 방식이 추천된다.

❄ 장단점

장점단점
객체들을 단계별로 생성 가능
생성 단계들을 연기할 수 있음
재귀적 단계 실행 가능
패턴이 여러 개의 새 클래스들을 생성해야 하므로 코드의 전반적인 복잡성이 증가
제품들의 다양한 표현을 만들 때 같은 생성 코드를 재사용할 수 있음매번 메서드를 호출하여 빌더를 거쳐 인스턴스화하기 때문에, 생성자보다 성능이 떨어짐
생성 비용 자체는 크지 않지만, 어플리케이션의 성능이 극도로 중요한 경우 문제가 됨
단일 책임 원칙
제품의 비즈니스 로직에서 복잡한 생성 코드를 고립시킬 수 있음

⭐ 빌더 패턴을 사용해야 하는 이유

  1. 필요한 데이터만 설정할 수 있다.
User user = User.builder()
				.name("Potato")
                .height(200)
                .iq(300)
                .build();
  1. 유연성을 확보할 수 있다.
    • 새로운 변수가 추가되는 상황이 생겨도 기존 코드에 영향을 주지 않을 수 있다.
  2. 가독성을 높일 수 있다.
    • 생성자로 객체를 생성하게 되면 매개변수가 많아질수록 가독성이 떨어진다.
    • 아래와 같은 코드는 각 매개변수가 무엇을 의미하는지 바로 파악하기 힘들다.
    User user = new User("Potato", 200, 300);
  3. 변경 가능성을 최소화할 수 있다.
    • 수정자 패턴(Setter)는 불필요하게 변경 가능성을 열어두게 될 수 있다.
      이는 유지보수 시 값이 할당된 지점을 찾기 힘들게 된다.
    • 값을 할당하는 시점이 객체의 생성 뿐이라면, 객체에 잘못된 값이 들어와도 그 지점을 찾기 쉬워진다.


🌙 빌더를 구현할 필요가 없는 경우

  1. 객체의 생성을 라이브러리로 위임하는 경우
  2. 변수의 개수가 2개 이하이며, 변경 가능성이 없는 경우

출처 - 빌더 패턴
출처 - [Java] 빌더 패턴(Builder Pattern)을 사용해야 하는 이유
출처 - 빌더(Builder) 패턴 - 완벽 마스터하기



이번 주도 마무리~!!! 끗!

0개의 댓글