빌더패턴 (Builder Pattern)
// 사람클래스
class Person {
private _name: string;
private _age: number;
private _email: string;
private _phone: string;
private _weight: number;
private _height: number;
constructor(name: string, age: number, email: string, phone: string, weight: number, height: number) {
this._name = name;
this._age = age;
this._email = email;
this._phone = phone;
this._weight = weight;
this._height = height;
}
get name(): string {
return this._name;
}
set name(value: string) {
this._name = value;
}
// ...
}
const person = new Person('John', 30, 'john@example.com', '010-1234-1234', 70, 175);
console.log(person);
// console.log
Person {
_name: 'John',
_age: 30,
_email: 'john@example.com',
_phone: '010-1234-1234',
_weight: 70,
_height: 175
}
Person 클래스를 생성할때, 6가지의 멤버변수가 존재한다.
Person클래스의 멤버변수가 무수히 많이 추가가 된다고 가정해보자.
ex: 국적, 혈액형, 취미, 특기, 주민번호, 여권번호, 직업, 성별...
속성을 일일히 추가하고, 필요한 메서드를 만들고 하다보면 객체를 생성하게 될때 복잡한 상황에 놓이게 될 수 있다.
그렇게 Person클래스를 생성할때, 수많은 매개변수가 필요하게 된다.
빌더패턴을 사용하는 이유는객체를 생성할 때 생성자에 여러 개의 매개변수를 전달해야 하는 복잡한 상황에서
객체의 일부 매개변수를 선택적으로 설정하고 객체 생성 코드를 단순화하여, 복잡한 코드의 가독성을 향상 시킬 수 있다.
// 사람클래스
class Person {
private _name: string;
private _age: number;
private _email: string;
private _phone: string;
private _weight: number;
private _height: number;
constructor(name: string, age: number, email: string, phone: string, weight: number, height: number) {
this._name = name;
this._age = age;
this._email = email;
this._phone = phone;
this._weight = weight;
this._height = height;
}
get name(): string {
return this._name;
}
set name(value: string) {
this._name = value;
}
// ...
}
class PersonBuilder {
private _name: string;
private _age: number;
private _email: string;
private _phone: string;
private _weight: number;
private _height: number;
constructor() { }
setName(name: string) : PersonBuilder {
this._name = name;
return this;
}
setAuth(email: string, phone: string) : PersonBuilder {
this._email = email;
this._phone = phone;
return this;
}
...
builder() {
return new Person(
this._name,
this._age,
this._email,
this._phone,
this._weight,
this._height
)
}
}
const person = new PersonBuilder().setName('Harry').setAuth('Harray@example.com', '010-1234-1234').build();
console.log(person);
// console.log
Person {
_name: 'Harry',
_age: undefined,
_email: 'Harray@example.com',
_phone: '010-1234-1234',
_weight: undefined,
_height: undefined
}
빌더패턴을 사용하여, 선택적으로 매개변수를 설정할 수 있으며, 다른 매개변수는 기본값으로 설정할 수 있다.
기본적인 구조는 객체의 값을 지정해주는 setter함수에서 this를 return 해준다.
this(자신)를 return 해줌으로써 메소드체이닝으로 이어서 메서드들을 사용할수있게 된다.
이후, 객체생성 시 필요한 매개변수만을 setter 하고 마지막에 build 메소드를 실행하여 클래스를 반환하여 객체를 생성한다.
이렇게 하게되면, 객체생성시 생성자의 매개변수의 순서에 의존하지 않을수 있으며, 가독성도 더욱 향상된다고 볼수있다.
빌더클래스에 새로운 메소드들을 추가하여, 객체 생성 시 새로운 설정옵션들을 제공하거나 기존 설정을 수정할 수 있다.
자바스크립트에서 클래스는 Syntax Sugar이기에, 클래스를 컴파일 돌려보면 함수의 prototype을 이용해서 구현이 되어있다.
// javascript로 컴파일된 코드
var Person = /** @class */ (function () {
function Person(name, age, email, phone, weight, height) {
this._name = name;
this._age = age;
this._email = email;
this._phone = phone;
this._weight = weight;
this._height = height;
}
Object.defineProperty(Person.prototype, "name", {
get: function () {
return this._name;
},
set: function (value) {
this._name = value;
},
enumerable: false,
configurable: true
});
return Person;
}());
var person = new Person('John', 30, 'john@example.com', '010-1234-1234', 70, 175);
console.log(person);
var PersonBuilder = /** @class */ (function () {
function PersonBuilder() {
}
PersonBuilder.prototype.setName = function (name) {
this._name = name;
return this;
};
PersonBuilder.prototype.setAuth = function (email, phone) {
this._email = email;
this._phone = phone;
return this;
};
PersonBuilder.prototype.build = function () {
return new Person(this._name, this._age, this._email, this._phone, this._weight, this._height);
};
return PersonBuilder;
}());
var personBuilder = new PersonBuilder().setName('Harry').setAuth('Harray@example.com', '010-1234-1234').build();
console.log(personBuilder);
var Programmer = /** @class */ (function () {
function Programmer() {
}
Programmer.prototype.workHard = function () {
return console.log(this.person.name + '님은 열심히일한다');
};
Programmer.prototype.meeting = function () {
return console.log(this.person.name + '님은 미팅한다');
};
Programmer.prototype.codeReview = function () {
return console.log(this.person.name + '님은 코드리뷰한다');
};
return Programmer;
}());
빌더패턴 사용시의 이점
- 객체생성 시 선택적인 생성
- 생성자 오버로딩 을 열거할필요가 없음
- js에서는 생성자 오버로딩이 지원안됨, 클래스당 하나의 생성자
- 생성자 매개변수 인자순서를 생각할 필요가 없음, 매개변수에 의존하지 않는 생성
- 빌더클래스를 통해서 확장성 있는 객체 생성
ps
자바에서는 @Builder 어노테이션을 제공해줌
자바에서는 클래스내부에 이너클래스를 만들어서 사용할수도 있음
'디자인패턴GoF > 생성패턴' 카테고리의 다른 글
| 자바스크립트로 이해해보는 싱글톤패턴 (SingleTone Pattern) In 생성패턴 (0) | 2023.11.27 |
|---|---|
| 자바스크립트로 이해해보는 추상팩토리패턴 (Abstract Factory Pattern) In 생성패턴 (0) | 2023.11.14 |
| 자바스크립트로 이해해보는 팩토리메소드패턴 (FactoryMethod Pattern) In 생성패턴 (0) | 2023.11.03 |
| 자바스크립트로 이해해보는 프로토타입패턴 (Prototype Pattern) In 생성패턴 (1) | 2023.10.29 |