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

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

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


当前回答

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();
       }
    }
 }

然后使用方面编织器将代码编译成这样:

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;
} 

其他回答

复制自Spring in Action

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.

不幸的是,让AOP在一个中等规模的组织中真正有用似乎非常困难。(编辑器的支持,控制感,事实上你从不那么重要的事情开始导致代码崩溃,人们回家找家人,等等。)

我把希望寄托在面向组合的编程上,这是越来越现实的东西。它连接了许多流行的想法,给你一些非常酷的东西。

这里有一个即将实现的实现:qi4j.org/

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

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

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

经典的例子是安全性和日志记录。不是在应用程序中编写代码来记录x的发生或检查对象z的安全访问控制,而是有一种正常代码的“带外”语言装置,它可以系统地将安全性或登录到本地没有它们的例程中,即使您的代码没有提供它——它也会得到照顾。

一个更具体的例子是操作系统提供对文件的访问控制。软件程序不需要检查访问限制,因为底层系统会为它做这些工作。

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

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();
       }
    }
 }

然后使用方面编织器将代码编译成这样:

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;
}