关于aop:什么是面向方面的编程?

What is aspect-oriented programming?

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

这个问题是相关的,但并不是问它:

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

  • IMAO,问题中提供的链接比这里接受的链接有更清晰和彻底的答案。读这个问题的人可能会先读。


AOP解决了横切关注点的问题,横切关注点是以不同方法重复的任何类型的代码,通常不能完全重构到自己的模块中,比如日志记录或验证。因此,使用AOP,您可以将这些东西从主代码中去掉,并像这样垂直定义它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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();
       }
    }
 }

然后使用AspectWeaver将代码编译为:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

  • 那么,您需要语言支持吗?你的例子用什么语言?
  • 这是伪代码,但最著名的例子是AspectJ,它是一个Java的AOP修改,它使用了一种类似的技术,称为CutPosits。
  • 实际上,它们被称为切入点:)
  • 那有点像其他的或等的班级吗?或者是因为你只是在使用一个非常简单的例子?
  • 我不会将日志记录和验证称为"杂项"问题。虽然您可以有一个"misc"或"util"方面,但这有点草率。
  • 巫毒。我觉得OOP太过分了。
  • 马克,这是不是像装饰一个方法的入口点和出口点?
  • @如果它是为了截取或插入这些点上的代码,那么可以将其视为AOP。
  • @艾登贝尔,如果在远处看不见的动作可以被认为是巫术,那么是的,那就是巫术。在moose元编程中,方法修饰符(如before、after、around、inner、augment)就是这样做的。它掩盖了程序的执行流。这些几乎不可能被跟踪,特别是当它们来自系统的方面版本时,它称之为角色。有了这些,人们就可以组成错综复杂的系统。
  • AOP和单例模式有什么相似之处吗?
  • @哈沙克:不,它们是两个不相关的概念
  • @Markcidade我对AOP有一个了解,但我仍然在学习单例模式。我将能够在今后的工作中找出不同之处。谢谢。
  • @Markcidade,我需要一些帮助来理解AOP有帮助的真实场景。我看到的例子主要是关于日志记录和跟踪的,这对我来说很有意义。你能给我指出除此之外的一些用例吗?我不清楚它应该在哪里使用。此外,考虑到创建代理的性能惩罚,它们是否用于生产中?对不起,如果我的问题太幼稚的话。
  • 据我所知,在生产中使用代理。另一个用例包括事务。您可能不想在代码中到处添加与事务相关的代码。相反,您可以在AOP中使用事务方面,并且只将该关注点的代码放在那里,然后将其编织到您想要应用它的方法中。
  • 在我看来,这个概念非常类似于,例如,烧瓶或姜戈装饰师。有人能证实这一点吗?
  • 在许多支持插件的应用程序中,每个插件本质上都是一个方面,插件系统实现与AOP相同的目标。唯一的区别是插件通过自己的插件系统连接到应用程序中,插件是用基本编程语言编写的,而不是使用AOP扩展和AOP附带的所有极端陷阱/开放性。


不幸的是,要使AOP在一个普通的中型组织中真正发挥作用似乎非常困难。(编辑支持、控制感、你从导致代码腐烂的不太重要的事情开始、人们回到他们的家庭等等)

我把我的希望寄托在面向复合的编程上,这是一个越来越现实的东西。它与许多流行的想法联系在一起,给你一些很酷的东西。

看看下面的一个新的实现:qi4j.org/

事实上,我认为AOP的一个优点也是它的致命弱点:它是非侵入性的,如果可以的话,让人们忽略它,所以在大多数组织中,它将被视为次要问题。

  • 不过,它仍然包含一些非常有效的点


从副本复制完整性(爱因斯坦):

典型的例子是安全性和日志记录。不是在应用程序中编写代码来记录X的发生,或者检查对象Z的安全访问控制,而是有一种语言装置"带外"的正常代码,它可以系统地将安全性注入或登录到通常不具有安全性的例程中,即使您的代码不提供安全性,也要小心的。

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

如果你认为在我的经验中你需要AOP,你实际上需要投入更多的时间和精力在你的系统中进行适当的元数据管理,重点放在深思熟虑的结构/系统设计上。


从Spring中复制

AOP is often defined as a technique that promotes separation of
concerns in a software system. Systems are composed of several
components, each responsible for a specific piece of functionality.
But often these components also carry additional responsibilities
beyond their core functionality. System services such as logging,
transaction management, and security often find their way into
components whose core responsibilities is something else. These system
services are commonly referred to as cross-cutting concerns because
they tend to cut across multiple components in a system.


从副本复制完整(蜂鸣器):

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


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

下面是.NET中的一个示例。它使用代理类拦截方法调用并在saif方法调用之前或之后执行代码。

在.NET核心和C中使用autopac和dynamicproxy的面向方面编程(AOP)


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

SpringAOP(面向方面编程)框架用于模块化各个方面的横切关注点。简单地说,它只是拦截一些进程的拦截器,例如,当一个方法被执行时,SpringAOP可以劫持执行方法,并在方法执行之前或之后添加额外的功能。

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

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


AOP是一种更好地为跨越多个边界的功能模块化应用程序的方法。AOP是封装这些特性并遵循单一职责的另一种方法,它将这些横切关注点(日志、错误处理等)从应用程序的主要组件中移出。当适当地使用AOP时,随着时间的推移,可以在应用程序中产生更高的可维护性和可扩展性级别。