一、装饰者模式定义

装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象。这种为对象动态添加职责的方式就称为装饰者模式。装饰者对象和它所装饰的对象拥有一致的接口,对于用户来说是透明的。

和java等语言不同的是,java的装饰器模式是给对象动态添加职责,javascript中,给对象添加职责的能力是与生俱来的,更侧重于给函数动态添加职责。

二、java中的装饰者模式实现

package com.bobo.shejimoshi.derector;

public class Plane {
public void fire(){
System.out.println("发射普通子弹");
}
}
package com.bobo.shejimoshi.derector;

public class MissileDecorator {
private Plane plane;
public MissileDecorator(Plane plane){
this.plane=plane; } public void fire(){
plane.fire();
System.out.println("发射导弹");
}
}

可见在java等传统语言中,给对象动态增加职责的方式,并没有真正地改动对象自身,而是将对象放入另一个对象之中,这些对象都具有相同的对外接口。

三、javascript中的装饰者模式实现

3.1为javascript对象添加职责

在javascript中,给对象添加职责是与生俱来的本领。同样是上面的例子,在javascript中可以这么实现:

//装饰者模式
var plane={
fire:function(){
console.log("发射普通子弹");
},
}; var missileDecorator=function(){
console.log("发射导弹");
}; var fire1=plane.fire;
plane.fire=function(){
fire1();
missileDecorator();
}; plane.fire();

3.2为javascript函数添加职责

为函数添加一些功能,在java等语言中貌似只能直接改写该函数,这显然违反了开放—封闭原则;

如果不想更改原函数,可以像上面的例子,通过保存原函数引用的方式来改写某个函数,这种方式一种是需要借助中间变量保存原函数的引用,此外还会遇到this劫持的问题。

因此,比较好的方式是利用AOP来进行函数装饰。

Function.prototype.before

Function.prototype.before=function(beforeFn){
var _self=this;//保存原函数的引用
return function(){
beforeFn.apply(this,arguments);
return _self.apply(this,arguments);
};
}; document.getElementById=document.getElementById.before(function(){
alert();
}); var sel=document.getElementById('colorSelect');

如果想根据上一个函数的执行结果决定函数是否执行,甚至还可以这样写Function.prototype.before

Function.prototype.before=function(beforeFn){
var _self=this;
return function(){
if(beforeFn.apply(this,arguments)!==false){
_self.apply(this,arguments);
} };
};

使用这种方法还可以动态改变函数的参数:

    var func=function(param){
console.log(param);
};
func=func.before(function(param){
param.b='b';
});
func({'a':'a'});//输出 'a':a,'b':b

Function.prototype.after

Function.prototype.after=function(afterFn){
var _self=this;
return function(){
var ret=_self.apply(this,arguments);
afterFn.apply(this,arguments);
return ret;
};
};

javascript设计模式学习之十五——装饰者模式的更多相关文章

  1. javascript设计模式学习之十二——享元模式

    一.享元模式的定义及使用场景 享元模式是为了解决性能问题而诞生的设计模式,这和大部分设计模式为了提高程序复用性的原因不太一样,如果系统中因为创建了大量类似对象而导致内存占用过高,享元模式就非常有用了. ...

  2. javascript设计模式学习之十四——中介者模式

    一.中介者模式的定义和应用场景 中介者模式的作用在于解除对象之间的紧耦合关系,增加一个中介者之后,所有对象都通过中介者来通信,而不是互相引用,当一个对象发生变化的时候,仅需要通知中介者即可.从而将网状 ...

  3. Java 设计模式系列(十五)迭代器模式(Iterator)

    Java 设计模式系列(十五)迭代器模式(Iterator) 迭代器模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(interna ...

  4. javascript基础学习(十五)

    javascript之cookie 学习要点: cookie介绍 创建与获取cookie cookie的编码 cookie的生存期 cookie的路径 cookie的domain cookie的sec ...

  5. javascript设计模式学习之十六——状态模式

    一.状态模式的定义 状态模式的关键是区分事务内部和外部的状态,事务内部状态改变往往会带来事务的行为改变. 状态模式中有意思的一点是,一般我们谈到封装,都是优先封装对象的行为,而非对象的状态.但在状态模 ...

  6. javascript设计模式学习之十——组合模式

    一.组合模式定义及使用场景 组合模式将对象组合成树形结构,用以表示“部分—整体”的层次结构,除了用来表示树形结构之外,组合模式还可以利用对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性. ...

  7. 设计模式学习总结(五)创建者模式(Builder)

    创建者模式,主要针对某些产品有类似的生产步骤,且有需要有先后顺序的进行各个部件的生成. 一.示例展示: 通过学习及总结,以下是我完成的创建者模式的示例: 1.创建产品类:Laptop public c ...

  8. JavaScript中常见的十五种设计模式

    在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”. 在JavaScript中并没有类这种概念,JS中的函数属于一等对象,在JS中定义一个对象非常简单(var obj = {}), ...

  9. 【转】设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

    设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据"单一职责原则",我们应该尽量将对象细化,使其只负责或呈现单一的职 ...

随机推荐

  1. XML基础知识

    1.XML:(entension mark language) 可扩展的标记语言格式化的文本文件html(Hype Text Mark Language)(超文本标记语言)主要用于显示2.特点 一个良 ...

  2. Hrbustoj 2252 完全背包

    一个变形的完全背包 题是第一次团队赛的热身题...看别人博客看到这道题忽然就不会了 然后想了半天还是没想出来...上oj找了提交排名..发现自己弄出来的奇怪的办法居然用时最短... 问装m最低要多少的 ...

  3. Grand Theft Auto V 图形研究(2)

    原文链接 http://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study-part-2/   Level of Detail 如 ...

  4. Natural Language Processing Computational Linguistics

    http://www.nltk.org/book/ch00.html After this, the pace picks up, and we move on to a series of chap ...

  5. JAVA函数的返回值类型详解以及生成随机数的例题

    函数的四要素:函数名.输入.输出(返回).加工. 函数分为两种:一种是有返回值得函数,一种是没有返回值的函数. 1. 定义:没有返回值的函数:(当我不需要函数的计算结果再拿出来进行运算的时候,我就不需 ...

  6. OneDrive无法正常登录

    可能是DNS被污染 手动设置DNS 134.170.108.26 onedrive.live.com134.170.108.152 skyapi.onedrive.live.com

  7. javaee基本环境搭建

    安装包 安装jdk :D:\Program Files\Java\jdk1.7.0_17 下载tomcat:E:\apache-tomcat-6.0.36 下载maven:E:\apache-mave ...

  8. LINQ延迟查询的例子

    //linq延迟查询.两次查询结果不同 List<string> l = new List<string>() { "aaa", "bbb&quo ...

  9. Bootstrap 辅组类和响应式工具

    1.情景文本颜色 //各种色调的字体 <p class="text-muted">Bootstrap 视频教程</p> <p class=" ...

  10. Delphi Memory-Mapped File简单示例

    { Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira } unit MainFrm; ...