装饰器模式
对客户透明的方式动态地给一个对象附加上更多的责任,同时又不改变其结构。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
装饰器要素
1.抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
2.具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
3.装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
4.具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
例子
咖啡,可加牛奶,也可加糖,或者都加。
//装饰着模式
var DP = require("./DesignPattern.js");
function Icoffee() {
DP.Interface(this, ['showCoffee', 'getPrice']);
}
function Coffee(name, price) {
this.__proto__ = new Icoffee();
var _name, _price;
_name = name;
_price = price;
this.showCoffee = function () {
console.log(_name + 'coffee');
}
this.getPrice = function () {
return _price;
}
}
function Decorator(Coffee) {
var _coffee;
_coffee = Coffee;
this.showCoffee = function () {
_coffee.showCoffee();
}
this.getPrice = function () {
return _coffee.getPrice();
}
}
function Sugar(Coffee) {
this.__proto__ = new Decorator(Coffee);
this.showCoffee = function () {
console.log('加糖');
this.__proto__.showCoffee();
}
this.getPrice = function () {
return this.__proto__.getPrice() + 5;
}
}
function Milk(Coffee) {
this.__proto__ = new Decorator(Coffee);
this.showCoffee = function () {
console.log('加牛奶');
this.__proto__.showCoffee();
}
this.getPrice = function () {
this.__proto__.getPrice();
return this.__proto__.getPrice() + 5;
}
}
var coffee = new Coffee("拿铁", 20);
var sugar = new Sugar(coffee);
sugar.showCoffee();
console.log(sugar.getPrice());
console.log('--------------------------------------------');
var milk = new Milk(coffee);
milk.showCoffee();
console.log(milk.getPrice());
console.log('--------------------------------------------');
var sugarmilk = new Milk(sugar);
sugarmilk.showCoffee();
console.log(sugarmilk.getPrice());
console.log('--------------------------------------------');
var sugarmilkmilk = new Milk(sugarmilk);
sugarmilkmilk.showCoffee();
console.log(sugarmilkmilk.getPrice());
装饰器模式优点:
1.装饰类和被装饰类可以独立发展,不会相互耦合。
2.装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。就增加功能来说,装饰器模式相比生成子类更为灵活。
适用场景:
1.扩展一个类的功能。
2.动态增加功能,动态撤销。