装饰者模式 详解

定义

Decorator是一种结构型设计模式,旨在促进代码复用;
装饰者模式可以动态的给一个对象增加其他职责;就扩展功能来说,装饰者模式比生成子类更为灵活。

角色

  • 抽象构件角色(AbstractComponent):定义对象的接口,可以给这些对象动态增加职责;
  • 抽象装饰角色(AbstractDecorator):维护一个指向Component实例的引用,并且定义了与Component一致的接口;
  • 具体构件角色(ConcreteComponent):定义具体的对象,Decorator可以给它增加额外的职责;
  • 具体装饰角色(ConcreteDecorator):具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责;

从网上找到的类图
enter image description here

适用场景

  • 当需要修改现有的系统,希望在系统中为对象添加额外的功* 能,而不需要大量修改它们的底层代码;
  • 包含了需要大量不同类型对象的功能;

例子

比如咖啡和调味品,包括很多种类的咖啡,调味品叶同样分为炼乳,巧克力,糖,牛奶等不同种类;其中咖啡和调味品都是需要单独收费的,这时候,咖啡作为基类,也就是装饰者模式中的抽象构件角色,不同种类的咖啡则继承自咖啡,其为具体构件角色,而在调味品中,调味品(同样继承咖啡,是咖啡的一部分)作为抽象装饰角色,不同的种类的调味品则作为具体具体装饰角色;


实现代码

  • 代码一
//衣服
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());

运行结果为:


优缺点

注意的是,如果管理不当,它会极大的复杂化应用程序结构,因为它向我们的命名空间引入了很多小型但类似的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值