装饰者模式的定义:

装饰者(decorator)模式能够在不改变对象自身的基础上,在程序运行期间给对像动态的添加职责。与继承相比,装饰者是一种更轻便灵活的做法。

装饰者模式的特点:

可以动态的给某个对象添加额外的职责,而不会影响从这个类中派生的其它对象;

继承的一些缺点:

  1. 继承会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之改变;

  2. 超类的内部细节对于子类是可见的,继承常常被认为破坏了封装性;

传统面向对象的装饰者和JavaScript装饰者对比:

1.模拟传统面向对象语言的装饰者模式

//模拟传统语言的装饰者

//原始的飞机类
var Plan = function () {
}; Plan.prototype.fire = function () {
console.log('发射普通子弹');
}; //装饰类
var MissileDecorator = function (plan) {
this.plan = plan;
} MissileDecorator.prototype.fire = function () {
this.plan.fire();
console.log('发射导弹!');
}; var plan = new Plan();
plan = new MissileDecorator(plan);
plan.fire();

2.JavaScript中的装饰者模式

装饰者模式将一个对象嵌入到另一个对象之中,实际上相当于这个对象被另一个对像包装起来,形成一条包装链。请求随着这条包装链依次传递到所有的对象,每个对象都有处理这条请求的机会。


var Plan1 = {
fire: function () {
console.log('发射普通的子弹');
}
}; var missileDecorator= function () {
console.log('发射导弹!');
}; var fire = Plan1.fire; Plan1.fire=function () {
fire();
missileDecorator();
}; Plan1.fire();

装饰函数

在JavaScript中可以很方便的给某个对象扩展属性和方法,但却很难在不改动某个函数源代码的情况下,给该函数添加一些额外的功能。也就是在代码运行期间,我们很难切入某个函数的执行环境。

1.使用装饰者模式例子

//对window.onload的处理

window.onload=function () {
console.log('test');
}; var _onload= window.onload || function () {}; window.onload=function () {
_onload();
console.log('自己的处理函数');
};

2.使用AOP(面向切面编程)装饰函数

主要是以为在JavaScript中会存在随着函数的调用,this的指向发生变化,导致执行结果发生变化。

2.1.封装的before函数

在需要执行的函数之前执行某个新添加的功能函数

//是新添加的函数在旧函数之前执行
Function.prototype.before=function (beforefn) {
var _this= this; //保存旧函数的引用
return function () { //返回包含旧函数和新函数的“代理”函数
beforefn.apply(this,arguments); //执行新函数,且保证this不被劫持,新函数接受的参数
// 也会被原封不动的传入旧函数,新函数在旧函数之前执行
return _this.apply(this,arguments);
};
};
2.2.封装的after函数

在需要执行的函数之后执行某个新添加的功能函数


//新添加的函数在旧函数之后执行
Function.prototype.after=function (afterfn) {
var _this=this;
return function () {
var ret=_this.apply(this,arguments);
afterfn.apply(this,arguments);
return ret;
};
};
2.3.不污染Function原型的做法
var before=function (fn, before) {
return function () {
before.apply(this,arguments);
return fn.apply(this,arguments);
};
}; function func1(){console.log('1')}
function func2() {console.log('2')} var a=before(func1,func2); // a=before(a,func1);
a();

装饰者模式用法示例:

1.ajax动态添加参数

使用装饰者模式动态的改变ajax函数,传输的参数

//是新添加的函数在旧函数之前执行
Function.prototype.before=function (beforefn) {
var _this= this; //保存旧函数的引用
return function () { //返回包含旧函数和新函数的“代理”函数
beforefn.apply(this,arguments); //执行新函数,且保证this不被劫持,新函数接受的参数
// 也会被原封不动的传入旧函数,新函数在旧函数之前执行
return _this.apply(this,arguments);
};
}; var func = function (param) {
console.log(param);
}; func = func.before(function (param) {
param.b = 'b';
}); func({b:'222'}); //给ajax请求动态添加参数的例子
var ajax=function (type,url,param) {
console.log(param);
}; var getToken=function () {
return 'Token';
}; ajax=ajax.before(function (type, url, param) {
param.token=getToken();
}); ajax('get','http://www.jn.com',{name:'zhiqiang'});

2.表单验证并且提交

装饰者模式分离表单验证和提交的函数

Function.prototype.before=function (beforefn) {
var _this= this; //保存旧函数的引用
return function () { //返回包含旧函数和新函数的“代理”函数
beforefn.apply(this,arguments); //执行新函数,且保证this不被劫持,新函数接受的参数
// 也会被原封不动的传入旧函数,新函数在旧函数之前执行
return _this.apply(this,arguments);
};
}; var validata=function () {
if(username.value===''){
alert('用户名不能为空!')
return false;
}
if(password.value===''){
alert('密码不能为空!')
return false;
}
} var formSubmit=function () {
var param={
username=username.value;
password=password.value;
} ajax('post','http://www.mn.com',param);
} formSubmit= formSubmit.before(validata); submitBtn.onclick=function () {
formSubmit();
}

总结:

装饰者模式和代理模式的区别:

  1. 代理模式的目的是,当直接访问本体不方便或者不符合需要时,为这个本体提供一个代替者。本体定义了关键功能,而代理提供了或者拒绝对他的访问,或者是在访问本体之前做一些额外的事情。

  2. 装饰者模式的作用就是为对象动态的加入某些行为。


 
 
 

JavaScript设计模式----装饰者模式的更多相关文章

  1. javascript设计模式——装饰者模式

    前面的话 在程序开发中,许多时候都并不希望某个类天生就非常庞大,一次性包含许多职责.那么可以使用装饰者模式.装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象.本文将 ...

  2. 从ES6重新认识JavaScript设计模式: 装饰器模式

    1 什么是装饰器模式 向一个现有的对象添加新的功能,同时又不改变其结构的设计模式被称为装饰器模式(Decorator Pattern),它是作为现有的类的一个包装(Wrapper). 可以将装饰器理解 ...

  3. 读书笔记之 - javascript 设计模式 - 装饰者模式

    本章讨论的是一种为对象增添特性的技术,它并不使用创建新子类这种手段. 装饰者模式可以透明地把对象包装在具有同样接口的另一对象之中,这样一来,你可以给一些方法添加一些行为,然后将方法调用传递给原始对象. ...

  4. JavaScript设计模式—装饰器模式

    装饰器模式介绍 为对象添加新的功能,不改变其原有的结构和功能,原有的功能还是可以使用,跟适配器模式不一样,适配器模式原有的已经不能使用了,装饰器示例比如手机壳 UML类图和代码示例 Circle示原来 ...

  5. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  6. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  7. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  8. javascript的装饰者模式Decorator

    刚开始看这段代码有点绕,现在回过头来看,so easy! Function.prototype.before = function(beforefn){ var _self = this; retur ...

  9. 从源码角度理解Java设计模式——装饰者模式

    一.饰器者模式介绍 装饰者模式定义:在不改变原有对象的基础上附加功能,相比生成子类更灵活. 适用场景:动态的给一个对象添加或者撤销功能. 优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个 ...

随机推荐

  1. 算法练习LeetCode初级算法之数组

    删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数     官方解答:  同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...

  2. [剑指Offer]8-二叉树的下一个节点

    链接 https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPa ...

  3. Head First Servlets & JSP 学习笔记 第九章 —— 使用JSTL

    JSTL1.1 不是JSP2.0规范的一部分!你能访问Servlet和JSP API 不意味着你能访问JSTL! 使用JSTL之前,需要将两个文件("jstl.jar" 和 &qu ...

  4. stark组件开发之列表页面应用示例

    已经解决的,自定义的扩展函数,功能.但是 不可能返回. 一个 固定的页面把!  应该是,点击那条 记录之后的编辑, 就会跳转到相应的,编辑页面.所以 这个标签的  <a href="/ ...

  5. MySQL开发——【字段类型、约束】

    创建数据表 基本语法: create table 数据表名称( 字段名称 字段类型 字段约束, ... )[表选项]; 字段类型 整数型 ,有符号型,可以表示 ,有符号型,可以表示 mediumint ...

  6. MongoDB、Hbase、Redis等NoSQL分析

    NoSQL的四大种类 NoSQL数据库在整个数据库领域的江湖地位已经不言而喻.在大数据时代,虽然RDBMS很优秀,但是面对快速增长的数据规模和日渐复杂的数据模型,RDBMS渐渐力不从心,无法应对很多数 ...

  7. 对于PHP面试知识点的小结

    基础篇 了解大部分数组处理函数 字符串处理函数(区别 mb_ 系列函数) & 引用,结合案例分析 == 与 === 区别 isset 与 empty 区别 全部魔术函数理解 static.$t ...

  8. JAVA 8 主要新特性 ----------------(一)总纲

    一.版本中数据结构的修改浅析 二.JDK1.8优点概括 三.新功能Lambda表达式入门 四.Lambda函数式接口 五.Lambda方法引用与构造器引用 六.集合Stream API 七.新时间日期 ...

  9. javascript的常用事件

  10. maven学习pom

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...