介绍

装饰者提供比继承更有弹性的替代方案。 装饰者用用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数)。

装饰者用于通过重载方法的形式添加新功能,该模式可以在被装饰者前面或者后面加上自己的行为以达到特定的目的。

正文

那么装饰者模式有什么好处呢?前面说了,装饰者是一种实现继承的替代方案。当脚本运行时,在子类中增加行为会影响原有类所有的实例,而装饰者却不然。取而代之的是它能给不同对象各自添加新行为。如下代码所示:

//需要装饰的类(函数)
function Macbook() {
this.cost = function () {
return 1000;
};
} function Memory(macbook) {
this.cost = function () {
return macbook.cost() + 75;
};
} function BlurayDrive(macbook) {
this.cost = function () {
return macbook.cost() + 300;
};
} function Insurance(macbook) {
this.cost = function () {
return macbook.cost() + 250;
};
} // 用法
var myMacbook = new Insurance(new BlurayDrive(new Memory(new Macbook())));
console.log(myMacbook.cost()); 下面是另一个实例,当我们在装饰者对象上调用performTask时,它不仅具有一些装饰者的行为,同时也调用了下层对象的performTask函数。 function ConcreteClass() {
this.performTask = function () {
this.preTask();
console.log('doing something');
this.postTask();
};
} function AbstractDecorator(decorated) {
this.performTask = function () {
decorated.performTask();
};
} function ConcreteDecoratorClass(decorated) {
this.base = AbstractDecorator;
this.base(decorated); decorated.preTask = function () {
console.log('pre-calling..');
}; decorated.postTask = function () {
console.log('post-calling..');
}; } var concrete = new ConcreteClass();
var decorator1 = new ConcreteDecoratorClass(concrete);
var decorator2 = new ConcreteDecoratorClass(decorator1);
decorator2.performTask(); 再来一个彻底的例子: var tree = {};
tree.decorate = function () {
console.log('Make sure the tree won\'t fall');
}; tree.getDecorator = function (deco) {
tree[deco].prototype = this;
return new tree[deco];
}; tree.RedBalls = function () {
this.decorate = function () {
this.RedBalls.prototype.decorate(); // 第7步:先执行原型(这时候是Angel了)的decorate方法
console.log('Put on some red balls'); // 第8步 再输出 red
// 将这2步作为RedBalls的decorate方法
}
}; tree.BlueBalls = function () {
this.decorate = function () {
this.BlueBalls.prototype.decorate(); // 第1步:先执行原型的decorate方法,也就是tree.decorate()
console.log('Add blue balls'); // 第2步 再输出blue
// 将这2步作为BlueBalls的decorate方法
}
}; tree.Angel = function () {
this.decorate = function () {
this.Angel.prototype.decorate(); // 第4步:先执行原型(这时候是BlueBalls了)的decorate方法
console.log('An angel on the top'); // 第5步 再输出angel
// 将这2步作为Angel的decorate方法
}
}; tree = tree.getDecorator('BlueBalls'); // 第3步:将BlueBalls对象赋给tree,这时候父原型里的getDecorator依然可用
tree = tree.getDecorator('Angel'); // 第6步:将Angel对象赋给tree,这时候父原型的父原型里的getDecorator依然可用
tree = tree.getDecorator('RedBalls'); // 第9步:将RedBalls对象赋给tree tree.decorate(); // 第10步:执行RedBalls对象的decorate方法 总结 装饰者模式是为已有功能动态地添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用该函数包装所要装饰的已有函数对象,因此,当需要执行特殊行为的时候,调用代码就可以根据需要有选择地、按顺序地使用装饰功能来包装对象。优点是把类(函数)的核心职责和装饰功能区分开了。 同步与推荐 本文已同步至目录索引:深入理解JavaScript系列 深入理解JavaScript系列文章,包括了原创,翻译,转载等各类型的文章,如果对你有用,请推荐支持一把,给大叔写作的动力。

最新文章

  1. AOJ 0118 Property Distribution【DFS】
  2. EasyUI DateTimeBox设置默认时间的注意点
  3. 基于OpenSSL实现C/S架构中的https会话
  4. spring容器初始化执行某个方法
  5. va_list使用
  6. Reservoir Sampling - 蓄水池抽样
  7. Interleaving String——Leetcode
  8. [转] gdb 查看vector, list, map 内容
  9. zookeeper_00:zookeeper注意事项
  10. Mysql 笔记:
  11. PHP-变量(www.w3school.com.cn/php)
  12. Linux IO barrier
  13. [进程管理]linux 下 进程和线程的区别(baidu 面试)
  14. 关于JS递归函数细化认识及实用实例
  15. Oracle中Union与Union All的区别(适用多个数据库)
  16. npoi生成excel流并在客户端下载(html+后台 )
  17. 学号 20175223 《Java程序设计》第 5 周学习总结
  18. 【Python3练习题 015】 一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下。求它在第10次落地时,共经过多少米?第10次反弹多高?
  19. collection管理程序中不同类别的资源
  20. Android 编程下 WebView 加载一个网页如何得到网页的 Cookie 值

热门文章

  1. 「CF 600E」 Lomsat gelral
  2. opencv.js小案例
  3. python中一些算法数列
  4. 【bzoj3309】DZY Loves Math 莫比乌斯反演+线性筛
  5. 洛谷P3355 骑士共存问题(最小割)
  6. jvm学习笔记之对象详解
  7. Python第四次作业
  8. CBoard 看板参数管理
  9. 使用Swagger生成简单接口文档
  10. mysql ibdata 单独存储