装饰者模式 详解
2016-06-20 19:28
411 查看
定义
Decorator是一种结构型设计模式,旨在促进代码复用;装饰者模式可以动态的给一个对象增加其他职责;就扩展功能来说,装饰者模式比生成子类更为灵活。
角色
抽象构件角色(AbstractComponent):定义对象的接口,可以给这些对象动态增加职责;抽象装饰角色(AbstractDecorator):维护一个指向Component实例的引用,并且定义了与Component一致的接口;
具体构件角色(ConcreteComponent):定义具体的对象,Decorator可以给它增加额外的职责;
具体装饰角色(ConcreteDecorator):具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责;
从网上找到的类图
适用场景
当需要修改现有的系统,希望在系统中为对象添加额外的功* 能,而不需要大量修改它们的底层代码;包含了需要大量不同类型对象的功能;
例子
比如咖啡和调味品,包括很多种类的咖啡,调味品叶同样分为炼乳,巧克力,糖,牛奶等不同种类;其中咖啡和调味品都是需要单独收费的,这时候,咖啡作为基类,也就是装饰者模式中的抽象构件角色,不同种类的咖啡则继承自咖啡,其为具体构件角色,而在调味品中,调味品(同样继承咖啡,是咖啡的一部分)作为抽象装饰角色,不同的种类的调味品则作为具体具体装饰角色;实现代码
代码一//衣服 function WhiteClothes() { }; WhiteClothes.prototype = { getPrice : function() { return 1000; } }; function YellowClothes() { }; YellowClothes.prototype = { getPrice : function() { return 800; } }; //搭配 function Hat(clothes) { this.clothes = clothes; }; Hat.prototype = { getPrice : function() { return this.clothes.getPrice() + 100; } }; function Tie(clothes) { this.clothes = clothes; }; Tie.prototype = { getPrice : function() { return this.clothes.getPrice() + 120; } }; var clothes = new WhiteClothes(); //白衣服搭配帽子 var hat = new Hat(clothes); console.log(hat.getPrice()); //白衣服搭配领带 var tie = new Tie(clothes); console.log(tie.getPrice()); //白衣服搭配帽子和领带 var hattie = new Tie(hat); console.log(hattie.getPrice());
实现结果为
代码二
//抽象组件者 var MacbookPro = function () { }; //具体组件者 MacbookPro.prototype = { addEngraving : function () { }, addParallels : function () { }, add4GBRam : function () { }, add8GBRam : function () { }, addCase : function () { }, getPrice : function () { return 900.00; } }; //继承函数 function extend( subClass, superClass ){ var F = function(){}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; // 此处指向superClass的prototype 比直接保存superClass使用更为方便 subClass.superclass = superClass.prototype; if( superClass.prototype.constructor === Object.prototype.constructor ){ superClass.prototype.constructor = superClass; } } //中间装饰者 var MacbookDecorator = function (macbook) { this.macbook = macbook; }; MacbookDecorator.prototype = { addEngraving : function () { return this.macbook.addEngraving(); }, addParallels : function () { return this.macbook.addParallels(); }, add4GBRam : function () { return this.macbook.add4GBRam(); }, add8GBRam : function () { return this.macbook.add8GBRam(); }, addCase : function () { return this.macbook.addCase(); }, getPrice : function () { return 900.00; } }; //具体装饰者 var CaseDecorator = function (macbook) { CaseDecorator.superclass.constructor.call(this,macbook); }; //扩展超类 extend(CaseDecorator, MacbookDecorator); CaseDecorator.prototype.addCase = function () { return this.macbook.addCase() + "Adding case to macbook"; }; CaseDecorator.prototype.getPrice = function () { return this.macbook.getPrice() + 45.00; }; var pro = new MacbookPro(); console.log(pro.getPrice()); pro = new CaseDecorator(pro) console.log(pro.getPrice());
运行结果为:
优缺点
注意的是,如果管理不当,它会极大的复杂化应用程序结构,因为它向我们的命名空间引入了很多小型但类似的对象。相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用