美文网首页
面向切面编程笔记(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