美文网首页
面向切面编程笔记(JavaScript描述)

面向切面编程笔记(JavaScript描述)

作者: 罗坤_23333 | 来源:发表于2018-09-16 16:23 被阅读0次
面向切面编程(Aspect-Oriented-Programming)

面向切面编程,我对它的简单理解为:为了能通用的在函数前后执行某些操作。虽然目前AOP对JavaScript并不是热门话题,但是JavaScript一些新特性已经开始运用这一思想了。

为了能通用的在函数前后执行某些操作

    function test(arg1) {
        console.log(2);
        return arg1;
    }

假设当前有一个 test 函数,我们需要测试 test 函数执行时消耗的时间,那么最先想到的做法是:

    var start = new Date();
    test("a");
    var end = new Date();
    console.log('spend:' + (end - start));

但如果需要测试更多的函数,我们就需要编写更多的 start、end,为了能通用的在函数前后执行某些操作,我们尝试引用面向切面编程(AOP):

Function.prototype.before = function(fn){
    var __test = this;
    return function beforeClosure() {
        fn();
        return __test.apply(this, arguments);
    }
}
Function.prototype.after = function(fn){
    var __beforeClosure = this;
    return function afterClosure() {
        var result = __beforeClosure.apply(this, arguments);
        fn();
        return result;
    }
}

最后测试代码test被改为:

    var start = 0
    var end = 0
    function startTime(){
        start = new Date()
    }
    
    function endTime(){
        end = new Date()
        console.log('speed: '+ (end - start))
    }
    
    test.before(startTime).after(endTime)('c')

严格模式下

    "use strict"
    
    Function.prototype.before = function(fn){
        return (function(){
            fn()
            return this
        }.bind(this))()
    }
    
    Function.prototype.after = function(fn){
        return (function(){
            var result = this
            fn()
            return result
        }.bind(this))()
    }
    
    // 使用
    func.before(fn).after(fn)(args)
    

用AOP实现职责链

将after函数改写,使得第一个函数返回‘nextSuccessor’时,将请求继续传递给下一个函数。这里的字符串‘nextSuccessor’只是一种自定义的状态,为了更好表达前一步骤是否满足条件。
具体案例请移步《JavaScript设计模式与开发实践》一书中的职责链模式p.186
用AOP来实现职责链既简单又巧妙,但这种把函数叠在一起的方式,同时也叠加来函数的作用域,如果链条太长的话,也会对性能有较大的影响。

    Function.prototype.after = function(fn){
        var self = this;
        return function(){
            var ret = self.apply(this, arguments);
            if(ref === 'nextSuccessor'){
                return fn.apply(this,arguments)
            }
            
            return ref;
        }
    }
    
    var order = order500yuan.after( order200yuan ).afte( orderNormal )

装饰器模式

装饰器模式(Decorators)是一个典型的AOP应用。装饰器基本原理如下:

    @decorator
    class A{}
    
    // 相当于
    class A{}
    A = decorator(A) || A

因此对第一节进行改造

    function before(fn) {
        fn();
        return function(target, key, desc){}
    }


    @before(function(){start = new Date()})
    class MyTestableClass {
        constructor(fn){
            fn()
        }

        after(fn){
            fn();
            return this
        }
    }

    var start,end;
    new MyTestableClass(function(){
        // do something
    }).after(function(){end = new Date})

参考

相关文章

网友评论

      本文标题:面向切面编程笔记(JavaScript描述)

      本文链接:https://www.haomeiwen.com/subject/nmzwgftx.html