任何人都可以发布一个不记录的面向方面编程(AOP)的示例吗?
我查看了几个资源,但所有示例都是微不足道的日志记录。它有什么用?
直接从Aspect Oriented Programming: Radical Research in Modularity 借来的示例之一,Youtube 视频正在绘制到显示器上。在示例中,您有一个绘图程序,它由点、形状等组成,当这些对象发生更改时,您需要告诉显示器自行更新。如果不从某个方面处理它,您最终会重复自己很多次。
正如我所理解的,AOP 的创建是为了不重复自己可能与业务逻辑无关的横切关注点。使用方面,您可以将这些关注点模块化为方面。其中一个示例是记录,但您最终可能会重复许多不同的事情。从那以后它一直在发展,不再是面向方面的编程,而是面向方面的建模。
有关面向方面编程的更多信息可以从以下来源中找到:
安全
更友好的 asp.net webcontrols/webparts 错误消息
表现
验证:
[NotNull]
public string Property1 { get; set; }
[Length(Min = 10, Max = 20)]
public string Property2 { get; set; }
[Regex(Expression = @"[abc]{2}")]
public string Property3 { get; set; }
撤消 - 我正在调用支持撤消操作的第三方程序集。它要求调用者创建一个撤消上下文,调用程序集中的一些方法,然后销毁撤消上下文。上下文可以嵌套。此外,如果创建了上下文但处于需要重新启动应用程序的不良状态。
通常要使用撤消,我会写这样的东西
void foo()
{
int id = lib.create_undo_context();
try
{
lib.performsomeaction();
lib.performsomeaction();
lib.performsomeaction();
}
finally
{
lib.destroy_undo_context(id);
}
}
使用 PostSharp 我定义了一个名为 [Undo] 的属性,它在方法启动时创建撤消上下文,并在方法退出时销毁它(即使抛出异常) - 所以代码看起来像这样
[Undo]
void foo()
{
lib.performsomeaction();
lib.performsomeaction();
lib.performsomeaction();
}
实现这一点比我展示的要复杂一些,因为我确保即使在存在嵌套 Undo 上下文的情况下也会清理所有 undo 上下文 - 但你明白了。
另一个经典示例(如日志记录)是缓存。但其他例子更有趣。
依赖注入
严格来说,依赖注入只不过是一个横切关注点。许多依赖注入框架使用这样的基于属性的编程风格:
public class Car:IDisposable
{
[Inject]
public IGearBox Gearbox { get; set; }
...
}
[Inject] 属性也可以设计为不依赖于外部框架的方面。
Java 和 AspectJ 中的设计模式实现(Hannemann 和 Kiczales):http ://www.cs.ubc.ca/labs/spl/papers/2002/oopsla02-patterns.pdf
本文展示了如何使用 AspectJ 在 Java 中以更好的方式实现一些 GoF 设计模式
安全性 - 在执行某些方法之前检查用户是否具有适当的权限。
在 Java 中不能有多重继承。但是,通过使用 AOP,您可以拥有“有限的”多重继承。尝试用谷歌搜索以查看一些示例。
我也同意 Eyvid 的观点。Hannemann 和 Kiczales 的论文非常适合学习设计模式的基础知识并获得一些很棒的 AOP 示例。
公共不变检查。由于 PostSharp 1.5 会自带切面继承,即使是通过接口,也会带来很多新的机会。
我的相册将 aspectj 用于三件事:
第一个,特别是几乎直接来自关于 AOP 的谷歌技术演讲。它与大多数人认为的模块化方式不同。如果您对如何永久使用它感兴趣,绝对建议您观看。
交易管理。
在我看来,您不希望可能是事务一部分的对象知道它们在事务中。使用 AOP,您可以根据需要将对象组合成事务,而事务中的对象不需要知道它们在事务中的事实,甚至不需要知道 AOP 框架的存在。
我使用面向方面的编程来实现关键字搜索引擎。它更像是一个实验,但它展示了 AOP 如何用于日志记录和跟踪以外的目的。
基本上:
(i)引擎的用户将他/她的类标记为 KeywordSearchable,
(ii)引擎开始跟踪这些 KeywordSearchable 实例的创建和销毁,
(iii)引擎从这些 KeywordSearchable 对象中提取关键字,
(iv)给定对象和关键字,算法负责搜索。
有关这方面的更多详细信息,请访问http://montrealistic.blogspot.com/2011/08/aspect-orientation-implementation-of.html。
AOP 的例子:
假设您想在域模型的方法中记录一条消息:
示例:没有 AOP 的日志记录:
namespace Examples\Forum\Domain\Model;
class Forum {
/**
* @Flow\Inject
* @var \Examples\Forum\Logger\ApplicationLoggerInterface
*/
protected $applicationLogger;
/**
* Delete a forum post and log operation
*
* @param \Examples\Forum\Domain\Model\Post $post
* @return void
*/
public function deletePost(Post $post) {
$this->applicationLogger->log('Removing post ' . $post->getTitle(), LOG_INFO);
$this->posts->remove($post);
}
}
如果您必须在很多地方执行此操作,那么日志记录将成为您域模型逻辑的一部分。您必须在模型中注入所有日志记录依赖项。由于日志不是领域模型应该关心的,因此这是一个非功能性需求和所谓的横切关注点的示例。
使用 AOP,模型中的代码对日志一无所知。它将只专注于业务逻辑。