fe-interview icon indicating copy to clipboard operation
fe-interview copied to clipboard

[js] 第167天 你了解什么是AOP吗?它的作用是什么?举个例子

Open haizhilin2013 opened this issue 5 years ago • 4 comments

第167天 你了解什么是AOP吗?它的作用是什么?举个例子

haizhilin2013 avatar Sep 29 '19 20:09 haizhilin2013

AOP是面向切面编程,相对于面向对象编程,面向对象是将需求分为了不同的类并有着自己独立的行为,而面向切面编程就是将通用需求从不同的类不同的行为中提取出来很多个类共享一个功能(比如实例中的输入数据检查),一旦发生变化,修改这个行为即可而不用修改很多个类。 例子 AOP方法

// AOP工厂
var aopFactory = function(before, after){
  // 构造方法,在原方法前后增加执行方法
  function constructor(originFun){
      function $_class(...data){
          var result;
          proxy.before(data);
          result = originFun.apply(this, data);
          proxy.after(data);
          return result;
      }
      return $_class;
  }
  var proxy = {
      // 添加被代理方法,参数a为被代理方法,参数b为目标对象
      add : function(a, b){
          var funName;
          // 判断参数a类型,可以为方法或方法名
          if(typeof a == "function"){
              funName = a.name;
          }else if(typeof a == "string"){
              funName = a;
          }else{
              return;
          }
          // 不传对象时默认为window对象
          b = b || window;
          if(typeof b == "object" && b[funName]){
              // 用$_class替换原方法
              b[funName] = constructor(b[funName]);
          }
      },
      // 默认before为空方法
      before : function(){},
      // 默认after为空方法
      after : function(){}
  }
  // 注入特定的前后处理方法
  if(typeof before == "function"){
      proxy.before = before;
  }
  if(typeof after == "function"){
      proxy.after = after;
  }
  return proxy;
}

实例代码

let checkProxy;
// 验证参数是否为数字
function checkNumber(...data){
    var i, length;
    for(i=0, length=data[0].length; i<length; i++){
        if(typeof data[0][i] != "number")
            console.log(data[0][i] + "不是数字");
    }
}
// 将checkNumber方法作为前置通知,生成验证参数是否为数字的构造器
checkProxy = aopFactory(checkNumber);
// 加法
function Add(a,b){
    return a+b;
}
// 减法
function Minus(a,b){
    return a-b;
}

// 为加减法生成验证参数是否为数字的代理方法
checkProxy.add(Add);
checkProxy.add(Minus);

wwqin avatar Sep 30 '19 06:09 wwqin

  • 概念:AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后, 再通过“动态织入”的方式掺入业务逻辑模块中。

  • 好处:AOP的好处首先是可以保持业务逻辑模块的纯净和高内聚性,其次是可以很方便地复用日志统计等功能模块。

  • demo

Function.prototype.before = function (beforefn) {
    var _self = this;    //保存原函数引用
    return function () { //返回包含了原函数和新函数的"代理函数"
        beforefn.apply(this, arguments); //执行新函数,修正this
        return _self.apply(this, arguments); //执行原函数
    }
};

Function.prototype.after = function (afterfn) {
    var _self = this;
    return function () {
        var ret = _self.apply(this, arguments);
        afterfn.apply(this, arguments);
        return ret;
    }
};

var func = function () {
    console.log("2")
}

func = func.before(function () {
    console.log("1");
}).after(function () {
    console.log("3");
} )

func();

vkboo avatar Sep 30 '19 16:09 vkboo

装饰器版示例

export function interceptor(type, fun) {
  return (target, name, descripter) => {
    const cacheValue = descripter.value;
    if (type === "before") {
      descripter.value = () => {
        fun();
        cacheValue();
      };
    } else if (type === "after") {
      descripter.value = () => {
        cacheValue();
        fun();
      };
    }
  };
}
@interceptor("after", dosomethingAfter.bind(this, [1, 2, 3]))
@interceptor("before", dosomethingBefore)
onSubmitOrder() {
  console.log("order submitted");
}

Arweil avatar May 26 '20 07:05 Arweil

aop是面向切面编程,相比传统oop,aop能够在方法的前置,中置,后置中插入逻辑代码,对于项目中大量逻辑重复的代码,使用aop能很好的收口逻辑,将逻辑独立于业务代码之外,一处编写,多处使用.

xiaoqiangz avatar Jul 29 '22 03:07 xiaoqiangz