51

任何人都可以发布一个不记录的面向方面编程(AOP)的示例吗?

我查看了几个资源,但所有示例都是微不足道的日志记录。它有什么用?

4

14 回答 14

35

直接从Aspect Oriented Programming: Radical Research in Modularity 借来的示例之一,Youtube 视频正在绘制到显示器上。在示例中,您有一个绘图程序,它由点、形状等组成,当这些对象发生更改时,您需要告诉显示器自行更新。如果不从某个方面处理它,您最终会重复自己很多次。

正如我所理解的,AOP 的创建是为了不重复自己可能与业务逻辑无关的横切关注点。使用方面,您可以将这些关注点模块化为方面。其中一个示例是记录,但您最终可能会重复许多不同的事情。从那以后它一直在发展,不再是面向方面的编程,而是面向方面的建模。

有关面向方面编程的更多信息可以从以下来源中找到:

于 2008-11-28T12:12:55.537 回答
11

安全

  • 注入检查权限并阻止访问的代码

更友好的 asp.net webcontrols/webparts 错误消息

表现

  • 注入设置性能计数器的代码,以了解您的应用程序慢的地方
于 2008-11-28T11:50:31.557 回答
6

验证:

[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; }
于 2008-11-28T11:51:25.017 回答
6

撤消 - 我正在调用支持撤消操作的第三方程序集。它要求调用者创建一个撤消上下文,调用程序集中的一些方法,然后销毁撤消上下文。上下文可以嵌套。此外,如果创建了上下文但处于需要重新启动应用程序的不良状态。

通常要使用撤消,我会写这样的东西

    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 上下文 - 但你明白了。

于 2008-12-20T13:44:11.687 回答
5

另一个经典示例(如日志记录)是缓存。但其他例子更有趣。

于 2008-11-28T20:55:53.437 回答
5

依赖注入

严格来说,依赖注入只不过是一个横切关注点。许多依赖注入框架使用这样的基于属性的编程风格:

public class Car:IDisposable
{
    [Inject]
    public IGearBox Gearbox { get; set; }
   ...
}

[Inject] 属性也可以设计为不依赖于外部框架的方面。

于 2012-07-17T09:39:32.577 回答
4

Java 和 AspectJ 中的设计模式实现(Hannemann 和 Kiczales):http ://www.cs.ubc.ca/labs/spl/papers/2002/oopsla02-patterns.pdf

本文展示了如何使用 AspectJ 在 Java 中以更好的方式实现一些 GoF 设计模式

于 2008-11-28T12:31:28.197 回答
3

安全性 - 在执行某些方法之前检查用户是否具有适当的权限。

于 2008-11-28T11:44:13.533 回答
3

在 Java 中不能有多重继承。但是,通过使用 AOP,您可以拥有“有限的”多重继承。尝试用谷歌搜索以查看一些示例。

我也同意 Eyvid 的观点。Hannemann 和 Kiczales 的论文非常适合学习设计模式的基础知识并获得一些很棒的 AOP 示例。

于 2008-11-28T12:55:01.660 回答
2

公共不变检查。由于 PostSharp 1.5 会自带切面继承,即使是通过接口,也会带来很多新的机会。

于 2008-11-28T11:46:45.853 回答
2

我的相册将 aspectj 用于三件事:

  1. 将观察者“模式”实现为一段可重用的代码。
  2. 销毁特定类型呼叫的会话。
  3. 发生突变时在 DTO 上设置脏标志。

第一个,特别是几乎直接来自关于 AOP 的谷歌技术演讲。它与大多数人认为的模块化方式不同。如果您对如何永久使用它感兴趣,绝对建议您观看。

于 2008-11-28T20:43:03.697 回答
2

交易管理。

在我看来,您不希望可能是事务一部分的对象知道它们在事务中。使用 AOP,您可以根据需要将对象组合成事务,而事务中的对象不需要知道它们在事务中的事实,甚至不需要知道 AOP 框架的存在。

于 2010-04-08T15:32:09.460 回答
2

我使用面向方面的编程来实现关键字搜索引擎。它更像是一个实验,但它展示了 AOP 如何用于日志记录和跟踪以外的目的。

基本上:
(i)引擎的用户将他/她的类标记为 KeywordSearchable,
(ii)引擎开始跟踪这些 KeywordSearchable 实例的创建和销毁,
(iii)引擎从这些 KeywordSearchable 对象中提取关键字,
(iv)给定对象和关键字,算法负责搜索。

有关这方面的更多详细信息,请访问http://montrealistic.blogspot.com/2011/08/aspect-orientation-implementation-of.html

于 2011-08-01T05:52:16.287 回答
2

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,模型中的代码对日志一无所知。它将只专注于业务逻辑。

于 2014-11-23T18:14:35.333 回答