设计模式之装饰者模式

来源 | 看云
作者 | 汤姆大叔
介绍
正文
//需要装饰的类(函数)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对象赋给treetree.decorate(); // 第10步:执行RedBalls对象的decorate方法
总结
装饰者模式是为已有功能动态地添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用该函数包装所要装饰的已有函数对象。
因此,当需要执行特殊行为的时候,调用代码就可以根据需要有选择地、按顺序地使用装饰功能来包装对象。
优点是把类(函数)的核心职责和装饰功能区分开了。
本文完~

评论
