Skip to content

Instantly share code, notes, and snippets.

@KalpasWang
Last active December 19, 2019 15:16
Show Gist options
  • Save KalpasWang/74bd00f7c41708009691901788220d21 to your computer and use it in GitHub Desktop.
Save KalpasWang/74bd00f7c41708009691901788220d21 to your computer and use it in GitHub Desktop.
裝飾者模式
// 有個Sale物件代表一筆銷售,呼叫`Sale.getPrice()`取得價格,額外的功能可以用`Sale.decorate()`附加至物件上
// 用法
var sale = new Sale(100); // 售價是100
sale.decorate('fedtax'); // 加上聯邦稅//"$112.88元
sale sale.decorate('quebec'); // 再加上魅北克省稅
sale.decorate('money'); // 格式化成金額
sale.getPrice(); // "$112.88"
sale = new Sale(100); // 售價是100元
sale.decorate('fedtax'); // 加上聯邦稅
sale.decorate('cdn'); // 格式化成加拿大元
sale.getPrice(); // "CDN$ 105.00"
// 實作:將每個decorator實作為一個物件,包含一個會被覆寫的方法
function Sale(price) {
this.price = price || 100;
}
Sale.prototype.getPrice = function (){
return this.price;
}
Sale.decorators = {};
Sale.decorators.fedtax = {
getPrice: function () {
var price = this.uber.getPrice();
price += price * 5/100;
return price;
}
};
Sale.decorators.quebec = {
getPrice: function () {
var price = this.uber.getPrice();
Price += price * 7.5 / 100;
return price;
}
};
Sale.decorators.money = {
getPrice: function () {
return “$" + this.uber.getPrice().toFixed(2);
}
};
Sale.decorators.cdn = {
getPrice: function () {
return “CDN$" + this.uber.getPrice().toFixed(2);
}
};
Sale.prototype.decorate = function (decorator) {
var F function () {},
overrides = this.constructor.decorators [decorator],
i, newobj;
F.prototype = this;
newobj = new F();
newobj.uber = F.prototype;
for (i in overrides) {
if (overrides.hasOwnProperty(i)) {
newobj[i] = overrides[i];
}
}
return newobj;
};
// 改用串列實作,利用JavaScript的動態特性而不需要使用繼承。這個方式也可以卸除附加的裝飾
// 用法
var sale = new Sale(100); // 售價是180元
sale.decorate('fedtax'); // 加上聯邦稅
sale.decorate('quebec'); // 加上魁北克省稅
sale.decorate('money'); // 格式化成金額
sale.getPrice(); // "$112.88"
// 實作
function Sale(price) {
this.price = (price > 0) || 100;
this.decorators_list = [];
}
Sale.decorators = {};
Sale.decorators.fedtax = {
getPrice: function (price) {
return price + price * 5/100;
}
};
Sale.decorators.quebec = {
getPrice: function (price) {
return price + price * 7.5/100;
}
};
Sale.decorators.money = {
getPrice: function (price) {
return "$" + price.toFixed(2);
}
};
Sale.prototype.getPrice = function () {
var price = this.price,
i,
max = this.decorators_list.length,
name;
for (i = 0; i < max; i += 1) {
name = this.decorators_list[i];
price = Sale.decorators[name].getPrice(price);
}
return price;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment