[디자인 패턴] 빌더(Builder) 패턴

디자인 패턴 썸네일.png

❓빌더 패턴이 무엇일까?

빌더 패턴은 복합 객체 생성 과정을 별도의 독립된 클래스로 관리하는 패턴을 말합니다. 쉽게 말해 build라는 클래스 하나로 생성을 모두 관리할 수 있다는 건데요. 그렇다면 복합 객체, 복잡한 객체란 무엇을 뜻하는 것일까요?

❓복합 객체?

복합 객체는 내부적으로 다른 클래스의 객체를 포함하고 있는 것을 말합니다.

// Door 클래스 정의
class Door {
  operate(action) {
    console.log(`The door is ${action}.`);
  }
}

// Car 클래스 정의
class Car {
  constructor(model, year) {
    this.model = model;
    this.year = year;
    this.doors = [];
  }

  addDoor(color) {
    const newDoor = new Door();
    this.doors.push(newDoor);
  }

  operateAllDoors(action) {
    this.doors.forEach((door) => {
      door.operate(action);
    });
  }
}

이런 식으로 다른 클래스에 의존하게 되는데요, 이 복합 객체가 많아질 수록, 추상 메서드 패턴으로는 객체를 생성하기가 어려워집니다. 기존 생성 패턴의 한계로 빌더 패턴이 탄생하게 되었다는 것이죠.

❗빌더 패턴을 알아보자

빌더 패턴이 복합 객체를 관리하는데 좋은 패턴이라는 것을 알았습니다. 그렇다면 어떤식으로 동작하는 것일까요?

빌더 패턴.png

빌더 패턴에서 눈에 보이는 것은, ‘빌더’와 ‘알고리즘’입니다.

빌더는 추상화를 통해 복합 객체를 생성 관리 할 수 있는데요, 이렇게 만들어진 하위 클래스를 ConcreteBuilder라고 합니다.

알고리즘 역시 추상화를 통해서 모델의 생성 관리를 할 수 있습니다.

JS 코드를 통해 알아봅시다.

// Product: 자동차 객체
class Car {
  constructor() {
    this.make = '';
    this.model = '';
    this.year = '';
  }

  describe() {
    console.log(`Car: ${this.year} ${this.make} ${this.model}`);
  }
}

// Builder: 자동차 객체를 생성하기 위한 빌더 인터페이스
class CarBuilder {
  constructor() {
    this.car = new Car();
  }

  setMake(make) {
    this.car.make = make;
    return this;
  }

  setModel(model) {
    this.car.model = model;
    return this;
  }

  setYear(year) {
    this.car.year = year;
    return this;
  }

  build() {
    return this.car;
  }
}

const sportCar = new Builder().setMake('Ferrari').setModel('458').setYear('2023').build();

코드에서는 빌더 객체 sportCar라는 객체를 만들었습니다. 간단한 예시여서 추상화와 알고리즘을 분리하지 않았지만, 이렇게 builder를 통해 여러 객체를 만들 수 있다는 것입니다!

추상 팩토리와 비슷하게 보일 수 있지만, 추상 팩토리는 서브 단계에서 생성 절차가 완료되면 각각의 모델을 바로 반환하는데 반면, 빌더 패턴은 단계별 생성 절차가 모두 완료 되어야 복합 객체를 반환한다는 것입니다.

즉 추상 패턴은 각각의 부품에 의미를 부여하는 반면, 빌더 패턴은 부품이 전부 모여야 의미를 가진다는 것!

❓빌더 패턴의 단점

빌더 패턴은 알고리즘 덕분에 교환 가능성, 그리고 객체군 사이의 의존성을 없앨 수 있어 복잡성을 관리하기 편리합니다.

하지만 이는 작은 규모의 객체나 단순한 객체 생성에는 불필요한 작업일 수 있습니다. 이에 자원 낭비, 오버헤드가 발생할 수 있고, 오히려 유지보수에 어려윰을 가져다 줄 수 있습니다.

그러니 작은 규모의 객체나 생성 로직이 단순한 경우에는 사용하지 않는 것이 좋겠네요.

반응형