什么是面向方面的编程?


231

我了解面向对象的编程,并且很长时间以来一直在编写OO程序。人们似乎在谈论面向方面的编程,但是我从来没有真正了解过它是什么或如何使用它。基本范式是什么?

这个问题是相关的,但并没有完全提出:

面向方面的编程与面向对象的编程


5
IMAO,问题中提供的链接比此处接受的链接具有更清晰,更彻底的答案。人们可能会先阅读此问题。
David Chen

Answers:


198

AOP解决了横切关注点的问题,横切关注点可能是在不同方法中重复的任何类型的代码,通常无法像日志记录或验证那样完全重构为自己的模块。因此,使用AOP,您可以将这些内容排除在主代码之外,并按如下方式垂直定义它:

function mainProgram()
{ 
   var x =  foo();
   doSomethingWith(x);
   return x;
}

aspect logging
{ 
    before (mainProgram is called):
    { 
       log.Write("entering mainProgram");
    }

    after (mainProgram is called):
    { 
       log.Write(  "exiting mainProgram with return value of "
                  + mainProgram.returnValue);
    }
 } 

aspect verification
{ 
    before (doSomethingWith is called):
    { 
       if (doSomethingWith.arguments[0] == null) 
       { 
          throw NullArgumentException();
       }

       if (!doSomethingWith.caller.isAuthenticated)
       { 
          throw Securityexception();
       }
    }
 }

然后使用aspect-weaver将代码编译为以下代码:

function mainProgram()
{ 
   log.Write("entering mainProgram");

   var x = foo();   

   if (x == null) throw NullArgumentException();
   if (!mainProgramIsAuthenticated()) throw Securityexception();
   doSomethingWith(x);   

   log.Write("exiting mainProgram with return value of "+ x);
   return x;
} 

14
那么,您需要语言支持吗?您的示例使用哪种语言?
苏菲

8
这是伪代码,但最著名的示例是AspectJ,它是Java的AOP修改,它使用了一种称为割点的类似技术。
马克·西达德

71
巫毒教 我认为OOP太过分了。
艾登·贝尔

17
马克,这就像装饰方法的入口和出口吗?
FilipDupanović2011年

3
@AidenBell如果在远处看不见的动作可以被认为是巫毒教,那么是的,这就是巫毒教。在Moose元编程的情况下,方法修饰符(例如,之前,之后,周围,内部,增强)正是这样做的。它掩盖了程序的执行流程。这些几乎是不可能追踪的,尤其是当它们是从系统的方面版本(它称为角色)派生而来时。所有这一切都可以组成复杂的系统。
tchrist

13

不幸的是,要使AOP在普通的中型企业中真正有用似乎很难。(编辑人员的支持,控制感,您从导致代码腐烂的不太重要的事情开始,人们回到家中等事实开始)。

我寄希望于面向复合的编程,这越来越现实。它连接了许多流行的想法,并为您提供了非常酷的东西。

在这里查看一个即将实施的实现:qi4j.org/

PS。实际上,我认为AOP的优点之一还在于它的致命弱点:它的非侵入性,如果可以的话,让人们忽略它,因此在大多数组织中它将被视为次要问题。


8

为了完整性而从副本中复制(爱因斯坦):

经典示例是安全性和日志记录。与其在您的应用程序内编写代码以记录x的出现或检查对象z的安全访问控制,不如使用普通代码的“带外”语言措辞,它可以系统地注入安全性或登录没有天真地将其包含在其中的例程这样,即使您的代码不提供它,它也会得到照顾。

一个更具体的例子是操作系统提供对文件的访问控制。一个软件程序不需要检查访问限制,因为底层系统可以完成该工作。

如果您认为根据我的经验需要AOP,则实际上确实需要投入更多的时间和精力来进行系统内适当的元数据管理,并着重考虑周全的结构/系统设计。


7

从《春季行动》中复制

AOP通常被定义为一种促进软件系统中关注点分离的技术。系统由几个组件组成,每个组件负责特定的功能。但是,这些组件通常还承担核心功能以外的其他职责。诸如日志记录,事务管理和安全性之类的系统服务通常会进入组成其核心职责的组件。这些系统服务通常被称为跨领域关注点,因为它们倾向于跨越系统中的多个组件。


6

从副本中复制以确保完整性(蜂鸣器):

.NET中的类和方法属性是面向方面的编程的一种形式。您可以用属性修饰类/方法。在幕后,这会将代码添加到您的类/方法中,以执行属性的特定功能。例如,标记一个可序列化的类允许将其自动序列化以存储或传输到另一个系统。其他属性可能会将某些属性标记为不可序列化,并且这些属性将自动从序列化对象中省略。序列化是一个方面,由系统中的其他代码实现,并且通过应用“配置”属性(装饰)应用于类。


5

AOP可用于执行与应用程序的业务逻辑无关的操作,例如日志记录,缓存等。这些操作可放在应用程序的单独部分中,然后在整个应用程序中重复使用。通常有两种方法可以完成此任务。在方法之前/之后由预处理器自动注入代码,或附加代理类以拦截方法调用,然后可以在方法调用之前/之后执行操作。

这是.Net中的示例。它使用代理类拦截方法调用并在saif方法调用之后执行代码。

使用AutoFac和DynamicProxy在.NET Core和C#中进行面向方面的编程(AOP)


4

有一个AOP的例子,它以spring AOP为例。这个例子很容易理解。

Spring AOP(面向方面​​的编程)框架用于模块化方面的跨领域关注点。简而言之,它只是拦截某些进程的拦截器,例如,当方法执行时,Spring AOP可以劫持执行方法,并在方法执行之前或之后添加额外的功能。

参考:http : //www.mkyong.com/spring/spring-aop-examples-advice/


在计算中,面向方面的编程(AOP)是一种编程范例,旨在通过允许跨领域关注点的分离来提高模块化。
RF

3

AOP是一种更好地模块化您的应用程序以实现跨越多个边界的功能的方法。AOP是封装这些功能并通过将这些横切关注点(日志记录,错误处理等)移出应用程序的主要组件而遵循“单一职责”的另一种方法。如果使用得当,AOP会随着时间的流逝在您的应用程序中带来更高级别的可维护性和可扩展性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.