两当县 五寨县 海宁市 阿坝县 太白县 四川省 巴林右旗 柘城县 台东县 修武县 元阳县 屏边 施甸县 镇巴县 静乐县 墨竹工卡县

文章导航安卓资源苹果资源

pc软件网络操作系统工具编程服务器软件评测

安卓新闻资讯应用教程刷机教程tv资讯深度阅读安卓评测

苹果ios资讯苹果手机越狱备份教程美化教程ios软件教程mac教程

单机游戏角色扮演棋牌游戏体育竞技模拟经营其它游戏游戏工具

网游cf活动lol周免英雄lol礼包

手游最新动态手游评测手游活动手游问答

您的位置:单机游戏角色扮演 → 怪物猎人世界新装备介绍 怪物猎人世界新装备新系统一览

阿瓦山寨_前端也要学系列:设计模式之装饰者模式

标签:一言千金 辰溪县

什么是装饰者模式

今天我们来讲另外一个非常实用的设计模式:装饰者模式。这个名字听上去有些莫名其妙,不着急,我们先来记住它的一个别名:包装器模式

我们记着这两个名字来开始今天的文章。

首先还是上《设计模式》一书中的经典定义:

  1. 动态地给一个对象添加一些额外的职责。
  2. 就增加功能来说,装饰者模式相比生成子类更为灵活。

我们来分析一下这个定义。

给对象添加一些新的职责,我们很容易想到创建子类来继承父类,然后在子类上增加额外的职责。

那什么是动态地呢?应该就是说这些新添加的职责在类一开始创建的时候我们并不知道,而是在使用过程根据需要而添加的。

相比生成子类更为灵活,这句话让装饰者模式和子类继承赤裸裸的刀兵相见了。没有对比就没有伤害,那我们就用例子来验证这句话。

传统面向对象的实现

我们假设你是以为已经走上人生巅峰的汽车生产商,你的公司生产各种用途的汽车,某一天一个客户下单了四种汽车,分别是家用轿车、SUV、旅行车和跑车。我们很轻松地像下面这样进行交付了。

var Car = fun权力巅峰_2018年最新新闻网ction(){}

Car.prototype.start = function(){
    console.log("轰轰轰,启动正常!")
}

var Sedan = new car();// 小轿车
var Suv = new Car();// SUV
var Wagon=new Car();// 旅行车
var Roadster=new Car();// 跑车
//是不是又学会了几个英文单词?

过了几天客户找来了,说最近人们爱上了西藏自驾游,人们都希望能够选装一些方便越野和载物的功能,比如加装雪地胎、行李箱,升高底盘。

有经验的你满口答应下来,这个简单,于是你交付了下面的代码:

//SUV
Suv.prototype.changeTire = function(){
    console.log("我换了雪地胎");
} 
Suv.prototype.addHeight = function(){
     console.log("我升高了底盘");
}
Suv.prototype.addBox = function(){
    console.log("我安装了行李箱");
}
//Wagon
Wagon.prototype.changeTire = function(){
    console.log("我换了雪地胎");
} 
Wagon.prototype.addHeight = function(){
     console.log("我升高了底盘");
}
Wagon.prototype.addBox = function(){
    console.log("我安装了行李箱");
}
//Sedan
Sedan.prototype.changeTire = function(){
    console.log("我换了雪地胎");
} 
Sedan.prototype.addHeight = function(){
     console.log("我升高了底盘");
}
Sedan.prototype.addBox = function(){
    console.log("我安装了行李箱");
}

// 使用
var suv = new Suv();
suv.changeTire();
suv.addHeight();
suv.addBox();
suv.start();
...

你增加了多少种特性?3x3=9种。

你又问,我直接把这三个特性加在Car上不行吗?就不用这么麻烦了。

当然不行,因为我们还有一种车:Roadster跑车。

你能想象法拉利换了雪地胎背上行李箱升高底盘是个什么死样子吗?这么干的人肯定疯了。

如果我们把特性一股脑加在Car上,就避免不了这种情况的发生。

这个时候,就体现出子类继承的不灵活之处。

下面,装饰者模式就要正式登场了。

var Car=function (){}

Car.prototype.start=function(){
    console.log("轰轰轰,启动正常!")
}

// 创建装饰类(包装类)

var ChangeTireDec=function(car){
    this.car=car;
}
var AddHeightDec=function(car){
    this.car=car;
}
var AddBoxDec=function(car){
    this.car=car;
}

// 装饰类具有和超级基因优化液_2018年最新新闻网Car同样的特性,只不过额外执行了一些其他的操作

ChangeTireDec.prototype.start=function(){
    console.log("我换了雪地胎");
    this.car.start(厦门大学_2018年最新新闻网);
}

AddHeightDec.prototype.start=function(car){
    console.log("我升高了底盘");
    this.car.start();
}
AddBoxDec.prototype.start=function(car){
    console.log("我安装了行李箱");
    this.car.start();
}

// 使用
var suv=new Suv();

suv=new ChangeTireDec(suv);
suv=new AddHeightDec(suv);
suv=new AddBoxDec(suv);

suv.start();

上面的代码你增加了几种特性?只有三种!而且不管你是给SUV还是Wagon还是Sedan加装,都不需要再增加特性的代码。

这,就是装饰者模式的优势所在。

现在我们再回过头来看看GoF的定义:

  1. 动态地给一个对象添加一些额外的职责。
  2. 就增加功能来说,装饰者模式相比生成子类更为灵活。

怎么样,是不是如同1+1=2一样简单了?现在你应该也明白了为什么装饰者模式又叫座包装器模式了。因为它将类的原有特性包装起来,添加其他的特性,就像一个箱子一样。而且实现过程中,还满足了封闭-开放原则。

JavaScript的实现

上面的例子中,我们是模拟了传统的面向对象语言来解释什么是装饰者模式。我们都知道,要动态改变JavaScript对象非常容易,可以向操作变量一个操作对象,我们再来改写下上面的例子,让它更javasripty

var c四川大学_2018年最新新闻网ar = {
    start: function(){
        console.log("轰轰轰,正常启动!");
    }
}

var ChangeTireDec = function(){
        console.log("我换了雪地胎");
}
var AddHeightDec = function(){
    console.log("我升高了底盘");
}
var AddBoxDec = function(){
     console.log("我安装了行李箱");
}

var start1 = car.start;
car.start=function()dhc_2018年最新新闻网{
    ChangeTireDec();
    start1();
}

var start2=car.start;
car.start = function(){
    AddHeightDec();
    start2();
}

var start3=car.start();
car.start = function(){
    AddBoxDec();
    start3();
}

// 执行

car.start();

实际中的应用

从上面的例子我们可以看出来,我们不断的将car.start的引用赋值给临时变量,然后将原来的car.start指向新的对象--包含了原来对象的引用和新的特性的对象。这很好的保证了代码的开放-封闭原则,这是今天第二次提到这个原则了,就是对修改封闭,对新增开放。

特别当你要重构一个非常复杂的多人项目时,如拼团_2018年最新新闻网果你不想因为修改了同事的一行代码而引起“蝴蝶效应”,那么将他的方法整个打包赋值然后用装饰者模式增加新的功能,是一种非常安全而且高效的做法。

下一步,我们可以愉快的去使用装饰者模式啦!

当前文章:http://www-dabianzao-com.ruihot.cn/hn6kamqj/43c68_156197.html

发布时间:2019-04-22 07:52:35

澳门银河娱乐yh163am.com  陈美琪暴瘦成纸片人 粉丝吃惊不已  银河国际中心游戏厅  银河娱乐手机版yh163am.com  银河娱乐手机版yh163am.com  澳门银河娱乐场yh163am.com  银河国际手机网址2949  银河娱乐官网yh163am.com  澳门银河手机网站福建霞浦渔船失事致1人失联  澳门银河真人yh163am.com  

相关阅读 E3:《茶杯头》新DLC“甜蜜终章”公布 新角色登场走近“弹丸小国”的大农业js学习日记-变量的坑中财MBA联合会第14届主席王宇超:把握需求快速链接《饥荒:联机版》“暴食”活动将至,可惜不是自己吃

文章评论
发表评论

热门文章 投入2000万新元!新加坡总理谈为何承办美朝峰会?《刀剑神域》第三季人设公布 幼年桐人萌出一脸血使用TensorFlow给花朵????分类中兴通讯复牌:A股跌停,港股开盘大跌37.5%

最新文章 携多款精品手游登场 阿里游戏带你玩转2018ChinaJoy BTOC广工大MBA注重基础 打造华南最优质教育品牌 特斯拉员工在高速上开启Autopilot打瞌睡:自动驾驶让人犯困?说真的,你想要一个性爱机器人么?特斯拉Model 3销售没那么乐观,约四分之一订单被取消

人气排行 诺基亚X6手机推送固件更新:提升安卓8.1系统流畅性,新增后台锁定小米CDR招股书披露:一季度营收344亿元,出货量同比大涨鄂渝两地成立自然保护地联盟共护区域生态安全“老赖”站门口哭着不走 被法警强制带走文献纪录片《邓华上将》开机新闻发布会在京成功举办武汉首届乡村旅游节开幕 将发放50万张惠民门票西藏推广青稞良种“喜玛拉22号”打造第一主导品种