javascript设计模式学习之十五——装饰者模式
一、装饰者模式定义
装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象。这种为对象动态添加职责的方式就称为装饰者模式。装饰者对象和它所装饰的对象拥有一致的接口,对于用户来说是透明的。
和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设计模式学习之十五——装饰者模式的更多相关文章
- javascript设计模式学习之十二——享元模式
一.享元模式的定义及使用场景 享元模式是为了解决性能问题而诞生的设计模式,这和大部分设计模式为了提高程序复用性的原因不太一样,如果系统中因为创建了大量类似对象而导致内存占用过高,享元模式就非常有用了. ...
- javascript设计模式学习之十四——中介者模式
一.中介者模式的定义和应用场景 中介者模式的作用在于解除对象之间的紧耦合关系,增加一个中介者之后,所有对象都通过中介者来通信,而不是互相引用,当一个对象发生变化的时候,仅需要通知中介者即可.从而将网状 ...
- Java 设计模式系列(十五)迭代器模式(Iterator)
Java 设计模式系列(十五)迭代器模式(Iterator) 迭代器模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(interna ...
- javascript基础学习(十五)
javascript之cookie 学习要点: cookie介绍 创建与获取cookie cookie的编码 cookie的生存期 cookie的路径 cookie的domain cookie的sec ...
- javascript设计模式学习之十六——状态模式
一.状态模式的定义 状态模式的关键是区分事务内部和外部的状态,事务内部状态改变往往会带来事务的行为改变. 状态模式中有意思的一点是,一般我们谈到封装,都是优先封装对象的行为,而非对象的状态.但在状态模 ...
- javascript设计模式学习之十——组合模式
一.组合模式定义及使用场景 组合模式将对象组合成树形结构,用以表示“部分—整体”的层次结构,除了用来表示树形结构之外,组合模式还可以利用对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性. ...
- 设计模式学习总结(五)创建者模式(Builder)
创建者模式,主要针对某些产品有类似的生产步骤,且有需要有先后顺序的进行各个部件的生成. 一.示例展示: 通过学习及总结,以下是我完成的创建者模式的示例: 1.创建产品类:Laptop public c ...
- JavaScript中常见的十五种设计模式
在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”. 在JavaScript中并没有类这种概念,JS中的函数属于一等对象,在JS中定义一个对象非常简单(var obj = {}), ...
- 【转】设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)
设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据"单一职责原则",我们应该尽量将对象细化,使其只负责或呈现单一的职 ...
随机推荐
- PowerCmd-cmd命令行管理工具
缘由 看了大漠在慕课网关于angular的讲解,用到了PowerCmd.就百度一下准备下载,很小很实用的工具,发现有人总结了.备忘 http://www.cnblogs.com/xing901022/ ...
- Apache Storm 衍生项目之2 -- Trident-ML
欢迎转载,转载请注明出处,徽沪一郎,谢谢. 楔子 或许谈起storm是大数据实时计算框架已经让你不明觉厉,如果说storm还可以跟机器学习算法(ml)有机的结合在一起,是不是更加觉着高大尚呢.trid ...
- DS实验题 Old_Driver UnionFindSet结构
题目 思路 很典型的并查集问题,朋友A和B要合并到一个统一的集合中,也就是Union(A, B)操作,在Union操作中需要先找到A所属的集合的代表元和B所属集合的代表元,也就是使用Find(A)和F ...
- PHP / JavaScript / jQuery 表单验证与处理总结: 第①部分 PHP 表单验证与处理
PHP VERSION = 5.3.10 一.关于 $_REQUEST PHP 文档关于 $_REQUEST 的说明: 说明 默认情况下包含了 $_GET,$_POST 和 $_COOKIE 的数组. ...
- php配置相关
php.ini error_reporting //配置错误的显示方式 display_errors //此项优先级高于error_reporting,如果关闭该项,会返还http状态码,如果开启,则 ...
- jboss4.2.3建立oracle JMS应用
一.基本配置 1 增加oracle驱动文件,ojdbc6.jar,不能使用小于该版本的jdbc驱动,jboss-4.2.3.GA\server\default\lib 2 增加retrotransla ...
- js文档视口高度函数
objwin=window;objBody=document.body;objDel=document.documentElement; 关于弹窗时候用到 function getPageHeig ...
- Block的简单使用
代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数,并得到返回值. 代码块本质上是变量,只不过它存储的数据是一个函数体,因此名字 ...
- ASP.NET MVC3 通过Url传多个参数方法
MVC3通过URL传值,一般情况下都会遇到 [从客户端(&)中检测到有潜在危险的 Request.Path 值]的问题 这个问题的解决方法,我的其他博文已经有了说明,这里给出连接 ; [从客户 ...
- 【python】RGB图片到灰度图的转换
在做立体匹配求深度图的时候遇到这个问题,用惯了matlab的rgb2gray,倒是不熟悉python的实现,在网上找到了相关方案,记下来已作备用 RGB到灰度图转换公式: Y' = 0.299 R + ...