꼬꼬마 블로그

꼬꼬마의 기술 블로그

빌더 패턴은 객체 생성 패턴 중 하나입니다.

 

개인적으로 종종 봤었던 패턴이기도 하고 빌더 패턴을 이용하면 많은 멤버가 있는 클래스의 객체도 깔끔하게 생성할 수 있습니다.
예제는 모두 타입스크립트로 작성되었으니 참고해주세요.

 

빌더 패턴 없이는?

class Person {
  constructor(
    private name: string,
    private age: number,
    private address: string,
    private phone: string,
  ) { }

  getName() { return this.name; }

  getAge() { return this.age; }

  getAddress() { return this.address; }

  getPhone() { return this.phone; }
}

const person1 = new Person('choi', 19, '우리집', '010-1234-1234');
const person1 = new Person('jin', 23, null, null);

(코드의 길이가 꽤 길어 코드블럭으로 작성했습니다)

 

위와 같이 Person이라는 클래스는 4가지 멤버를 가집니다. 모든 멤버는 getter만 가집니다.

문제1. 가독성

person1객체를 만들때 4가지 인자를 넣어줍니다. 이때 'choi', 19, '...', '...'와 같이 각각의 인자가 무슨 값을 의미하는지 알기 힘듭니다.

 

또한 person2와 같이 null값을 넣어준다면 직접 null을 입력하여 넣어주어야합니다.

문제2. 개발자의 실수 그리고 헷갈려..

만약 인자의 순서를 잘못적는다면 직접 비교하며 찾아야합니다. 위의 예제보다 더 많은 멤버가 있다면 실수를 찾기는 더더욱 쉽지 않아집니다.

 

 

또한 인자의 순서를 위와 같은 IDE 혹은 에디터의 도움을 받아 작성하는 수 밖에 없습니다.

빌더 패턴 (Builder Pattern)

class Person {
  constructor(
    private name: string,
    private age: number,
    private address: string,
    private phone: string,
  ) { }

  getName() { return this.name; }
  getAge() { return this.age; }
  getAddress() { return this.address; }
  getPhone() { return this.phone; }
}

class PersonBuilder {
  private name: string;
  private age: number;
  private address: string;
  private phone: string;

  setName(name: string) {
    this.name = name;

    return this;
  }

  setAge(age: number) {
    this.age = age;

    return this;
  }

  setAddress(address: string) {
    this.address = address;

    return this;
  }

  setPhone(phone: string) {
    this.phone = phone;

    return this;
  }

  build() {
    return new Person(this.name, this.age, this.address, this.phone);
  }
}

const personBuilder = new PersonBuilder();
const person: Person = personBuilder
  .setName('choi')
  .setAge(19)
  .setAddress('우리집')
  .setPhone('010-1234-1234')
  .build();

PersonBuilder라는 클래스의 setOOO메서드들은 각각의 멤버를 set하고 this를 반환합니다. 그 후 마지막엔 build 메서드를 이용하여 객체를 반환하는 패턴입니다.

 

여기서 Builder클래스를 하나로 합쳐보도록 하겠습니다.

class Person {
  constructor(
    private name: string,
    private age: number,
    private address: string,
    private phone: string,
  ) { }

  getName() { return this.name; }

  getAge() { return this.age; }

  getAddress() { return this.address; }

  getPhone() { return this.phone; }

  static builder() {
    return new this.PersonBuilder();
  }

  static PersonBuilder = class {
    private name: string;
    private age: number;
    private address: string;
    private phone: string;

    setName(name: string) {
      this.name = name;

      return this;
    }

    setAge(age: number) {
      this.age = age;

      return this;
    }

    setAddress(address: string) {
      this.address = address;

      return this;
    }

    setPhone(phone: string) {
      this.phone = phone;

      return this;
    }

    build() {
      return new Person(this.name, this.age, this.address, this.phone);
    }
  }

}


const person = Person.builder()
  .setName('choi')
  .setAge(19)
  .setAddress('우리집')
  .setPhone('010-1234-1234')
  .build();

inner class를 사용하면 PersonBuilderPerson클래스 안에 넣을 수 있습니다. builder 메서드를 통해 PersonBuilder 객체를 반환하여 사용합니다.

 

 

빌더 패턴은 어렵지 않지만 코드를 더욱 간결하게 만들며 개발자가 이해하기 쉬운 코드를 짜도록 도와줍니다.

'개발 > 객체지향' 카테고리의 다른 글

어댑터 패턴 (Adapter Pattern)  (0) 2021.04.05
객체지향 SOLID 원칙  (2) 2021.03.27
싱글톤 패턴 (Singleton Pattern)  (0) 2020.08.06