设计模式——装饰者模式(为不同对象各自添加不同行为)
装饰者模式(可以理解成另一种继承方式)
背景:以飞机大战为例,不同类型的飞机已由构造工厂构造完毕,当飞机碰到血包或者敌机时,实现血量会有相应变化的功能;
我们知道用传统继承方法实现该功能就要为不同类型的飞机原型上增加该系列方法,会影响原有子类下的所有实例;
而装饰者模式可以在不改变对象(子类)自身的基础上,在程序运行期间,为不同对象各自动态添加行的行为;与继承相比装饰者是一种更轻便灵活的做法
下面一个demo:了解装饰者模式;
(在上一篇工厂方法模式的基础上进行的…)
//demo:
function PlaneFactory () {
//创建装饰池:储存装饰方法(名称)的作用;
this.decorator_list = [];
}
//创建装饰者对象:(添加相应的装饰方法)
PlaneFactory.prototype.decorators = {
eatOneLife : function (oP) {
oP.blood += 100;
},
eatTwoLife : function (oP) {
oP.blood += 200;
},
eatShrinkLife : function (oP) {
oP.blood -= 50;
}
}
//将装饰方法对应的类型存储到装饰池当中:
PlaneFactory.prototype.decorate = function (decorator) {
this.decorator_list.push(decorator);
}
//真正完成装饰者模式功能的方法:
PlaneFactory.prototype.done = function () {
for (var i = 0; i < this.decorator_list.length; i++) {
//找到装饰者对象中相应的方法并执行(参数为本身);
this.decorators[ this.decorator_list[i] ] && this.decorators[ this.decorator_list[i] ](this);
}
}
//清空装饰池方法:
PlaneFactory.prototype.empty = function () {
this.decorator_list = [];
}
//公共接口:
PlaneFactory.prototype.touch = function () {
console.log('die');
}
PlaneFactory.prototype.blood = 100;
//子类工厂:
PlaneFactory.prototype.SmallPlane = function () {
this.name = 'SmallPlane';
this.width = 100;
this.height = 100;
}
PlaneFactory.prototype.SmartPlane = function () {
this.name = 'SmartPlane';
this.width = 50;
this.height = 50;
this.track = function () {
console.log('track');
}
}
PlaneFactory.prototype.AttackPlane = function () {
this.name = 'AttackPlane';
this.width = 200;
this.height = 200;
this.attack = function () {
console.log('attack');
}
}
//真正完成工厂方法模式:
PlaneFactory.creat = function (type) {
if (PlaneFactory.prototype[type] == undefined) {
throw 'no this constructor';
}
if (PlaneFactory.prototype[type].prototype.__proto__ !== PlaneFactory.prototype) {
PlaneFactory.prototype[type].prototype = new PlaneFactory();
}
var oNewPlane = new PlaneFactory.prototype[type];
return oNewPlane;
}
//实现工厂方法创建对象:
var oAP = PlaneFactory.creat("AttackPlane");
var oSP = PlaneFactory.creat("SmartPlane");
//测试:由于原先采用工厂模式开发,无需更改代码,各个子类所创建的对象更不会相互影响;
oAP.decorate('eatOneLife'); // 碰血包:this.blood += 100; 200
oAP.decorate('eatShrinkLife'); // 碰敌机:this.blood -= 50; 150
oAP.done();
oAP.empty();
console.log(oAP.blood); // oAP最终行为:150;
oSP.decorate('eatTwoLife'); // 300;
oSP.decorate('eatTwoLife'); // 500;
oSP.done();
oSP.empty();
console.log(oSP.blood); // oSP最终行为:500;
//通过装饰者模式完美的为不同子类添加了行为,并且不会互相影响,还能更好的为之后添加各种行为;