Вопрос по javascript – Библиотеки AOP Javascript [закрыто]

29

Какую библиотеку Javascript AOP вы используете и каковы ее основные функции?

Ваш Ответ

3   ответа
30

Вот что я нашел до сих пор:

  • dotvoid's implementation, clean syntax, nice to use, the article is a good introduction on why/how to use the given code, supports introductions, but is bugged,
  • Dojo has what seems to be a good built-in implementation in dojox, here is a nice introduction on how to use it,
  • there is a plugin for jQuery, jquery-aop, with a rougher syntax, passing objects and methods in a javascript object,
  • AspectJS with an even rougher syntax (need to pass type of pointcut as arguments to a single method)

Как я уже сказал, код dotvoid не работает. Я немного исправил и получил что-то, что, кажется, работает лучше:

InvalidAspect = new Error("Missing a valid aspect. Aspect is not a function.");
InvalidObject = new Error("Missing valid object or an array of valid objects.");
InvalidMethod = new Error("Missing valid method to apply aspect on.");

function doBefore(beforeFunc,func){
    return function(){
        beforeFunc.apply(this,arguments);
        return func.apply(this,arguments);
    };  
}

function doAfter(func, afterFunc){
    return function(){
        var res = func.apply(this,arguments);
        afterFunc.apply(this,arguments);
        return res;   
    };
}

Aspects = function(){};
Aspects.prototype={
    _addIntroduction : function(intro, obj){
         for (var m in intro.prototype) {
              obj.prototype[m] = intro.prototype[m];
            }
        },

    addIntroduction : function(aspect, objs){
        var oType = typeof(objs);

        if (typeof(aspect) != 'function')
        throw(InvalidAspect);

        if (oType == 'function'){
            this._addIntroduction(aspect, objs);
        }
        else if (oType == 'object'){
            for (var n = 0; n < objs.length; n++){
                this._addIntroduction(aspect, objs[n]);
            }
        }
        else{
            throw InvalidObject;
        }
    },

    addBefore : function(aspect, obj, funcs){
          var fType = typeof(funcs);

          if (typeof(aspect) != 'function')
            throw(InvalidAspect);

          if (fType != 'object')
            funcs = Array(funcs);

          for (var n = 0; n < funcs.length; n++){
            var fName = funcs[n];
            var old = obj.prototype[fName];

            if (!old)
              throw InvalidMethod;

            var res = doBefore(aspect,old)
            obj.prototype[fName] = res;
        }
    },

    addAfter : function(aspect, obj, funcs) {
          if (typeof(aspect) != 'function')
            throw InvalidAspect;

          if (typeof(funcs) != 'object')
            funcs = Array(funcs);

          for (var n = 0; n < funcs.length; n++)
          {
            var fName = funcs[n];
            var old = obj.prototype[fName];

            if (!old)
              throw InvalidMethod;

            var res = doAfter(old,aspect);
            obj.prototype[fName] = res;
          }
        },

    addAround : function(aspect, obj, funcs){
          if (typeof(aspect) != 'function')
            throw InvalidAspect;

          if (typeof(funcs) != 'object')
            funcs = Array(funcs);

          for (var n = 0; n < funcs.length; n++)
          {
            var fName = funcs[n];
            var old = obj.prototype[fName];
            if (!old)
              throw InvalidMethod;

            var res = aspect(old);
            obj.prototype[fName] = res;
          }

          return true;
        }
}
Я проводил тесты по этому вопросу в IE7. Работает отлично. Более низкие версии не проверены, хотя. glmxndr
Работает ли код как-то в Internet Explorer? Так как мои тесты не прошли, я погуглил, и, похоже, в IE нет "prototype" -property ...
2014: я нашел эту все еще очень активную структуруjsAspect кажется, что делает то, что должен делать АОП!
3

Основываясь на решении dotvoid, я создал свою собственную версию JS AOP для нужд своих проектов. Я в основном хочу минимизировать затраты на настройку аспекта, поэтому я добавил функциональность настройки аспекта в Function.prototype.

Function.prototype.applyBefore = function (aspect, targetFuncNames) {
....
}

Мне также нужно поддерживать обратные вызовы aync, такие как поддержка аутентификации и авторизации для определенных методов. Например:

var authenticateAspect = function (error, success, context, args) {
    logger.log('authenticate (applyBefore async) aspect is being called');
    var request = $.ajax({
        url: "http://localhost/BlogWeb/api/user/authenticate",
        type: "GET",
        data: { username:'jeff', pwd:'jeff' },
        success: function (data) {
            if (data) {
                success();
            } else {
                error();
            }
        },
        error: error
    });
    return request;
};

Person.applyBefore(authenticateAspect, 'sendNotification');

var p1 = new Person();

p1.sendNotification();

Чтобы реализовать это, мне нужно запустить защиту и продолжить работу в случае успеха или остановить выполнение в случае ошибки.

var invalidAspect = new Error("Missing a valid aspect. Aspect is not a function."),
    invalidMethod = new Error("Missing valid method to apply aspect on.");

///Parameters: aspect - defines the methods we want call before or/and 
///             after each method call ob target obejct
///            targetFuncNames - target function names to apply aspects
///Return: it should return a new object with all aspects setup on target object
Function.prototype.applyBefore = function (aspect, targetFuncNames) {
    if (typeof (aspect) != 'function')
        throw invalidAspect;

    if (typeof (targetFuncNames) != 'object')
        targetFuncNames = Array(targetFuncNames);

    var targetObj = this;
    //error handling function

    // Copy the properties over onto the new prototype
    for (var i = 0, len = targetFuncNames.length; i < len; i++) {
        var funcName = targetFuncNames[i];
        var targetFunc = targetObj.prototype[funcName];

        if (!targetFunc)
            throw invalidMethod;


        targetObj.prototype[funcName] = function () {
            var self = this, args = arguments;
            var success = function() {
                return targetFunc.apply(self, args);
            };
            var error = function () {
                logger.log('applyBefore aspect failed to pass');
                //log the error and throw new error
                throw new Error('applyBefore aspect failed to pass');
            };

            var aspectResult = aspect.apply(null, Array.prototype.concat([error, success, self], args));
            return aspectResult;
        };
    }
};

Полная реализация может быть найдена вhttp://www.jeffjin.net/aop-with-javascript

13

Ты виделmeld.js а такжеaop.js от https://github.com/cujojs?

SpringSource предоставляет функциональность AOP там, в дополнение к куче других полезных вещей для продвинутых программистов Javascript.

Disclaimer: Я работаю на SpringSource.

Это довольно старый вопрос ... но спасибо за добавление. glmxndr

Похожие вопросы