• 面向切面对象AOP


    前言

      面向切面编程(思想)AOP Aspect Oriented  Programming,是面向对象基础上 更关注最终目标 而不关注中间的小目标,简而言之,就是我们的目标(例如constroller)触发了我们关注的方法,此时就执行我们的观察者行为,例如在目标的方法触发前做事,触发后做事等等。

      为了让大家更好的理解,这里把面向过程、面向对象先讲解一遍。

    面向过程编程(思想)POP

      Procedure  Oriented  Programming,面向过程编程思想(关注事情步骤,事情本身),将一件事情的整体看作是一个流程,我们更关注事情的流程、步骤。比如我去超市买菜,我要下楼,等红绿灯,走过几条街道,进入超市选择自己要的菜,然后排队买单。我会关注这些过程要经历的事件,步骤。

    面向对象编程(思想)OOP

      Object  Oriented  Programming,面向对象编程思想(关注中间有几个对象参与其中),将原有整体事情的步骤,拆分成小段,每一个小段封装成一个单独的事情(方法),不同的方法交给不同的人来做,例如我去超市买菜,我在家里出发,最终目的是在超市买菜,中间几个环节交给不同的人(对象)来帮我做:下楼(被人背下去),打车,选菜,排队等等都有人帮我做,我只要把这些顺序连起来,指挥不同的对象按照我要求的顺序执行便可。

    面向切面编程(思想)AOP

      Aspect Oriented  Programming,面向切面编程思想(面向对象基础上 更关注最终目标 而不关注中间的小目标),但要注意切面本身也是对象,比如我去超市买菜,我为起始对象,超市为目标对象,在我到超市之前所经历的事情都归纳到切面对象(下楼,打车,选菜,排队执行这些方法的人(对象)等等),连接点(管理切面对象中的方法按顺序执行),代理对象负责管理这些切面对象,切点为买菜(即在目标对象中触发我们关心的方法);

    案例

      这里就用js模拟了,js模拟简单些,java模拟的话思路也是一样的,而且java的spring本身用xml或注解就可以了,这里主要讲思想

    // 面向对象的方式
    let money = 100;
    
    class PersonA{
      static before(){
        console.log("走路去超市买菜");
      }
    }
    
    class My{
      static buy(){
        money -= 55;
        console.log("买完菜,减去55元");
      }
    }
    
    class PersonC{
      static after(){
        console.log("走路回家");
      }
    }
    
    PersonA.before();//走路去超市买菜
    My.buy();//买完菜,减去55元
    PersonC.after();//走路回家
    // 面向切面的方式
    class agency{//可以理解为过滤器
    
      before(){
        console.log("走路去超市");
      }
      
      buy(Func,spend){//代理对象
        this.before();
        Func(spend);
        this.after();
      }
      
      after(){
        console.log("走路回家");
      }
    
    }
    
    let agencyObj = new agency();//找代理,类似找人帮我们买菜送上门,这方式好处在于其他人还可以找代理买家具,买学习用品等等,我们生成了一次代理,然后传不同的任务进去让代理帮我们执行
    
    class Myself{
    
      buy(agency,spend){
        agencyObj.buy(agency,spend);//代理对象帮我们执行的买菜方法
      }
    }
    
    let my = new Myself(10000);//实例化自己
    //制定所要做的第一件事
    function buy(spend) {
      money -= spend;
      console.log("买完菜,减去"+spend+"元,还剩:"+money+"元");
    }
    my.buy(buy,55);//这里我们以为还是自己调用方法去买菜,实际底层是代理对象帮我们执行的买菜方法
    
    
    money = 1000;
    //制定所要做的第二件事
    function buy2(spend) {
      money -= spend;
      console.log("买完日用品,减去"+spend+"元,还剩:"+money+"元");
    }
    my.buy(buy2,198);
    //可以看到,每次我们只需要把最终要实现的功能交给代理,最终代理对象返回想要的结果给我们
    
    // 执行结果:
    //   走路去超市
    //   买完菜,减去55元,还剩:45元
    //   走路回家
    
    //   走路去超市
    //   买完日用品,减去198元,还剩:802元
    //   走路回家

      上面的before和after方法可以当成过滤器,比如我要得到的数据渲染前先解密,解密渲染后,部分数据用*替换这类场景。

    稍微复杂一点的使用方式

      设置前置方法--before,后置方法--after-returning,异常处理--after-throwing,最终执行--after,环绕--around;

      前置方法是在目标方法前执行,后置方法在目标方法之后执行,异常处理即处理异常事件,最终执行即不管发生什么都一定会触发的事件,环绕即在目标方法触发时先后执行的事件,类似前置方法加后置方法。

    案例:

    // 面向切面的方式
    class agency{//可以理解为过滤器
    
      beforeMethod(){
        console.log("走路去超市");
      }
      
      buy(Func,spend){//代理对象
        try{
          // 前置
          this.beforeMethod();
          // 环绕前
          // 目标方法(环绕的是目标的前后)
          // Func(spend);
          this.aroundMethod(Func,spend);
          // 环绕后
          // 后置
          this.afterReturningMethod();
        }catch(e){
          // 异常
          this.afterThrowingMethod();
        }finally{
          // 最终
          this.afterMethod();
        }
      }
      
      afterReturningMethod(){
        console.log("走路回家");
      }
    
      afterThrowingMethod(){
        console.log("代购有事,此单取消");
      }
    
      afterMethod(){
        console.log("谢谢您,辛苦啦");
      }
    
      aroundMethod(Func,spend){
        console.log("上电梯");
        Func(spend);
        console.log("下电梯");
      }
    
    }
    
    let agencyObj = new agency();//找代理,类似找人帮我们买菜送上门,这方式好处在于其他人还可以找代理买家具,买学习用品等等,我们生成了一次代理,然后传不同的任务进去让代理帮我们执行
    
    class Myself{
    
      buy(agency,spend){
        agencyObj.buy(agency,spend);//代理对象帮我们执行的买菜方法
      }
    }
    
    let my = new Myself(10000);//实例化自己
    //制定所要做的第一件事
    function buy(spend) {
      money -= spend;
      console.log("买完菜,减去"+spend+"元,还剩:"+money+"元");
    }
    my.buy(buy,55);//这里我们以为还是自己调用方法去买菜,实际底层是代理对象帮我们执行的买菜方法
    
    
    money = 1000;
    //制定所要做的第二件事
    function buy2(spend) {
      money -= spend;
      console.log("买完日用品,减去"+spend+"元,还剩:"+money+"元");
    }
    my.buy(buy2,198);
    //可以看到,每次我们只需要把最终要实现的功能交给代理,最终代理对象返回想要的结果给我们
    
    // 执行结果:
      // 走路去超市
      // 上电梯
      // 买完菜,减去55元,还剩:45元
      // 下电梯
      // 走路回家
      // 谢谢您,辛苦啦
    
      // 走路去超市
      // 上电梯
      // 买完日用品,减去198元,还剩:802元
      // 下电梯
      // 走路回家
      // 谢谢您,辛苦啦

      这里也可以设置为前置方法和后置方法为默认,其他方法体根据我们传入的参数值的不同(例如数字)来判断执行哪些方法,就是约定优于配置,大家约定俗成,会更有效率。

    思路

      面向切面的方式就是更注重结果而不注重中间实现的步骤,中间无论由多少个切面对象帮你做了事,都由一个代理对象来帮你管理执行,而我们需要做的就是把要做的事告诉代理对象。当然面向切面的方式是否使用要根据业务场景来定,如果发现有多个方法中间需要执行的步骤流程一致,而这些方法只需要拿到经过这些步骤之后所得到的结果,不关心中间发生了什么,就使用面向切面的方式。

  • 相关阅读:
    mysql免安装版配置+navicat测试
    查询SQL Version详细信息
    拆分数据库测试之--收缩数据库
    测试拆分比较大SQL Server数据库
    SQL捕捉blocking信息
    T-SQL 重复读(Double Read)问题的理解
    Node.js版-七夕无事,人艰勿拆,求别说...
    css实现三角箭头(兼容IE6)
    前端开发的基础知识点摘要
    jQuery原理系列-常用Dom操作
  • 原文地址:https://www.cnblogs.com/zxd66666/p/13227403.html
Copyright © 2020-2023  润新知