javascript装饰器模式

众所周知装饰器模式用于给对象在运行期间动态的增加某个功能,职责等。相较通过继承的方式来扩充对象的功能,装饰器显得更加灵活,首先,我们可以动态给对象选定某个装饰器,而不用hardcore继承对象来实现某个功能点。其次:继承的方式可能会导致子类繁多,仅仅为了增加某一个单一的功能点,显得有些多余了。

装饰器经典实现

首先来看看传统的decorator的实现吧!假设现有一类叫Person 的对象,该对象有个speak 方法。开始的时候Person 的对象只会说中文,现在我要让他说英文,那么可以这么做:

var Person = function(name) {
    this.name = name;
};

Person.prototype.speak = function() {
    console.log(‘你好!‘);
};

var SpeakEnglish = function(person) {
    this.person = person;
};

SpeakEnglish.prototype.speak = function() {
    this.speak();
    console.log(‘hello!‘);
};

var SpeakJapanese = function(person) {
    this.person = person;
};

SpeakJapanese.prototype.speak = function() {
    this.speak();
    console.log(‘こんにちは!‘);
};

var lufy = new Person(‘lufy‘);
var engLufy = new SpeakEnglish(lufy);
var japanLufy = new SpeakJapanese(engLufy);
japanLufy.speak();

通过包装对象的方式给原对象增加新的功能,而不会影响原对象的同类对象。通过上面的方式路飞现在可以说3个国家的语言了。

javascript装饰函数

对于javascript这类支持函数式编程的语言,我们要装饰对象的某个方法其实也可以更加简便,譬如说,通常我们写前端页面处理的时候需要监听窗口的onload 事件,但是同样一个onload 需要被多个地方监听,可以这么做:

var attachOnloadHandle = function(doit) {
    if(typeof window.onload !== ‘function‘) {
        window.onload = doit;
    }
    else {
        var func = window.onload;
        window.onload = function() {
            func();
            doit();
        };
    }
};

函数实现比较简单,但也算实用吧!

装饰器模式与AOP

AOP是面向切面编程的简写。其语意为把一些与核心业务模块无关的功能剥离出来,把整个系统划分为更小的粒度。在完成这些子模块的设计编码后再逐步包装起来完成更大的功能。

javascript动态装饰函数

通过前面的例子我们看到所谓装饰无非是在执行某个功能之前执行一些前置或后置处理,提供两个更加通用的接口:

Function.prototype.before = function(beforfunc) {
    var self = this;
    return function() {
        beforfunc.apply(this, arguments);
        self.apply(this, arguments);
    };
};

Function.prototype.after = function(afterfunc) {
    var self = this;
    return function() {
        self.apply(this, arguments);
        afterfunc.apply(this, arguments);
    };
};

试一试:

var func = function() {
    console.log(‘hello‘);
};
func.before(function() {
    console.log(‘你好‘);
}).after(function() {
    console.log(‘こんにちは!‘);
});

考虑到安全方面的因素,我们在给微信服务器发送一些请求的时候都需要带上accessToken 有些操作不需要带这个参数,通过AOP函数包装我们可以这样来做:

var getToken = function(cb) {
    //...
};
var preRequest = function(doit, params) {
    var self = this;
    getToken(function(err, token) {
        if(err) {
            //xxx
            return;
        }
        self.token = token;
        doit.apply(self, params);
    });
};

var make = function(host, name, func) {
    host[name] = function() {
        this.preRequest(this[‘_‘ + name], arguments);
    };
    host[‘_‘ + name] = func;
};

//获取卡券
make(exports, ‘getCard‘, function(cardId, cb) {
    var url = ‘http://www.wechat.com/xxxx‘ + this.token;
    //...
});
时间: 2024-10-05 14:48:29

javascript装饰器模式的相关文章

【设计模式】之装饰器模式

为什么会有装饰模式? 装饰模式是为了解决继承强依赖性和出现大量子类不方便管理问题而出现的.   1. 概述 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活. 原理:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数.装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法.修饰类必须和原来的类有相同的接口. 2. 模式中的角色 2.1 抽象构建(Component):定义一个抽象接口,用以给这些对象动态

Decorator Pattern(装饰器模式)Demo1

一个简单的装饰器模式例子,用来体现直接查询,缓存查询,和过滤敏感词汇 1 import java.sql.Connection; 2 import java.sql.PreparedStatement; 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.util.ArrayList; 6 import java.util.HashMap; 7 import java.util.List; 8 im

装饰器模式

定义:可以动态地添加修改类的功能 解析:一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法.使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性. $canvas1 = new IMooc\Canvas();$canvas1->init();$canvas1->addDecorator(new \IMooc\ColorDrawDecorator('green'));$canvas1->addDecorato

装饰器模式及JAVA IO流例子★★★☆☆

一.什么是装饰模式 通过关联机制给类增加行为,其行为的扩展由修饰对象来决定: 二.补充说明 与继承相似,不同点在于继承是在编译期间扩展父类,而装饰器模式在运行期间动态扩展原有对象: 或者说,继承是对类进行扩展,装饰模式是对对象进行扩展: 三.角色 抽象构件 具体构件 抽象装饰类 具体装饰类 说明:具体构件.抽象装饰类.具体装饰类的共同父类是抽象构件,具体装饰类继承抽象装饰类并在运行期间装饰具体构件: 四.例子 例子说明: 画家接口Painter,为抽象构件,有两个方法,获取画家描述信息及绘画:

装饰器模式与代理模式比较

当有这样的业务需求的时候——要为写好的代码在目标代码之前或者之后添加部分操作时,此时最笨的方法就是直接在目标代码的前后加上我们需要的功能代码,但是这样违背了java封装的特性.更好一点的方法就是使用设计模式——代理模式,然而,装饰器模式也有同类的功能,那么着两种设计模式到底有什么区别呢?下面就分别来学习一下这两种设计模式. 装饰器模式类图如下: 该类图包括几个部分:一个接口(装饰器与需要被装饰的实体类都需要实现该接口,公用方法在该接口中定义),一个实现类,一个装饰器的接口,具体实现的装饰器. 在

IOS设计模式之二(门面模式,装饰器模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 门面(Facade)模式(译者注:facade有些书籍译为门面,有些书籍译为外观,此处译为门面) 门面模式针对复杂的子系统提供了单一的接口,不需要暴漏一些列的类和API给用户,你仅仅暴漏一个简单统一的API. 下面的图解释了这个概念: 这个API的使用者

代理模式与装饰器模式的区别

代理模式与装饰器模式的区别,主要大于,从使用者(客户端)的角度来看的: //装饰器的客户public class Client{ public static void main(String[] args){ //客户指定了装饰者需要装饰的是哪一个类 Component component = new Decorator(new ConcreteComponent()); - }}//代理的客户public class Client{ public static void main(String

设计模式-装饰器模式(Decrator Model)

文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概述 装饰器模式在不改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.通常给一个对象添加功能,要么在类中直接进行修改,要么通过子类继承来扩展对象的功能,又或者使用装饰模式将相应的功能进行任意的组合,使功能的扩展变的具有灵活性和动态性.装饰模式是通过创建一个包装对象,也就是装饰来包裹真实的对象,

设计模式(三):装饰器模式

一.概述 装饰器模式动态地将责任附加到对象上.想要扩展功能,装饰者提供了有别于继承的另一种选择.简单描述就是包装对象,让对象提供新的行为. 二.解决问题 当一个类想要获得一个行为,我们会想到面向对象四大特性之一的继承,继承能够让子类从父类中获得行为,实现很好的代码复用.但这种继承而来的行为是在编译时静态决定的,而且所有的子类都会继承相同的行为.如果我们想要扩展对象的行为,就要创建一个子类来修改父类的方法(也就是覆盖父类行为),每扩展一个行为就要创建一个子类,这样会带来很多问题.第一,如果需要扩展