데코레이터 패턴(Decorator Pattern)
은 런타임에 필요한 기능을 객체에 동적으로 추가할 수 있는 디자인패턴 중 하나이다. 기대되는 행위를 사용자화하거나 설정할 수 있다. 평범한 객체로 시작하다가 동적으로 사용 가능한 데코레이터들 후보 중에서 원하는 것을 골라 객체에 기능을 추가해 나갈 수 있다. 바로 예시를 들어보자.
예시
물건을 파는 기능을 구현한다고 해보자. Sale 객체를 정의했는데 이는 판매건을 의미한다. 판매할 때 당연히 가격
이 존재하며 이는 여러 국가에서 판매한다고 가정했을때, 지역마다 정책이 달라질 것이다. 이럴 때 계산하는 방식을 다르게하는 기능을 동적으로 추가할 수 있다. 이를 장식한다고 표현한다.
var sale = new Sale(100);
sale = sale.decorate('tax'); // 세금 추가
sale = sale.decorate('money'); // 통화 형식 지정
sale.getPrice(); // "$110.22"
자바스크립트로 구현
모든 데코레이터(장식자) 객체에 특정 메서드를 포함하여 메서드를 덮어쓰게 만드는 두 가지 방법을 자바스크립트로 구현해보자. 각 데코레이터는 이전의 객체에서 기능이 추가된 객체를 상속한다.
구현1
// 1. 생성자, 프로토타입 메서드
function Sale(price) {
this.price = price || 100;
}
Sale.prototype.getPrice = function() {
return this.price;
}
// 2. 장식자 객체들을 클래스 프로퍼티로 구현
Sale.decorators = {};
Sale.decorators.tax = {
getPrice: function() {
var price = this.uber.getPrice();
price = ...
return price;
}
};
Sale.decorators.money = {
getPrice: function() {
return "$" + this.uber.getPrice().toFixed(2);
}
}
// 3. decorate() 구현
Sale.prototype.decorate = function(decorator) {
var F = function() {};
// decorator의 재정의된 함수를 불러오기 위함
var overrides = this.constructor.decorators[decorate];
var newObj;
F.prototype = this;
newObj = new F();
newObj.uber = F.prototype;
// overrides의 프로퍼티를 newObj에 복사하고 리턴
for (var i in overrides) {
if (overrides.hasOwnProperty(i)) {
newObj[i] = overrides[i];
}
}
return newObj;
};
구현2 - 목록을 사용
상속을 사용하지 않고 목록을 사용할 수 있다. 이전 메서드의 결과를 다음 메서드에 매개변수로 전달한다. 장식 취소나 제거가 쉽다는 장점이 있다.
function Sale(price) {
this.price = price || 100;
// 데코레이터들의 목록을 관리할 배열
this.decorators_list = [];
}
// 2. Sale 클래스 프로퍼티로 데코레이터 선언
Sale.decorators = {};
Sale.decorators.money = {
getPrice: function(price) {
return "$" + price.toFixed(2);
}
};
...
// 3. decorate 메서드 정의. 목록에 추가하는 역할
Sale.prototype.decorate = function(decorator) {
this.decorators_list.push(decorator);
}
// 4. Sale의 getPrice 메서드를 정의
Sale.prototype.getPrice = function() {
var price = this.price,
i,
max = this.decorators_list.length,
name;
// decorator의 목록을 검사해서 price를 가져온다
for (i = 0; i < max; i++) {
name = this.decorators_list[i];
price = Sale.decorators[name].getPrice(price);
}
return price;
}
참고
- 자바스크립트 디자인패턴 Book
'Programming > Javascript' 카테고리의 다른 글
자바스크립트(Javascript) 디자인패턴 - 퍼사드 패턴 (facade pattern) (0) | 2020.06.03 |
---|---|
자바스크립트(Javascript) 디자인패턴 - 전략 패턴 (strategy pattern) (0) | 2020.06.02 |
자바스크립트(Javascript) - 반복자(Iterator) 패턴 (0) | 2020.05.29 |
자바스크립트(Javascript) 디자인패턴 - 싱글톤패턴(Singleton Pattern) (0) | 2020.05.29 |
자바스크립트(Javascript) 함수의 기본 패턴들 (콜백, 메모이제이션, 커리) (0) | 2020.05.29 |
댓글