面向方面的编程示例

时间:2008-11-28 11:34:24

标签: aop

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

我查看了几个资源,但所有示例都是简单的日志记录。有什么用?

14 个答案:

答案 0 :(得分:33)

直接从这个Aspect Oriented Programming: Radical Research in Modularity, Youtube video借出的一个例子是绘画到显示器。在示例中,您有一个绘图程序,它由点,形状等组成,当发生对这些对象的更改时,您需要告诉显示器更新自身。如果不在一个方面处理它,你最终会重复一遍。

正如我所理解的那样,AOP的创建是为了不重复自己的交叉问题,这可能与业务逻辑无关。通过各方面,您可以将这些问题模块化到方面。其中一个例子是记录,但是你可能最终会重复一些不同的事情。它一直在发展,它不再是面向方面的编程,而是面向方面的建模。

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

答案 1 :(得分:11)

安全

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

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

性能

  • 注入设置性能计数器的代码,以便全面了解应用程序的运行速度

答案 2 :(得分: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; }

答案 3 :(得分:6)

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

通常使用undo我会写这样的东西

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

实现这个比我展示的要复杂一点,因为即使在存在嵌套的撤销上下文的情况下,我也确保清除所有撤消上下文 - 但是你明白了。

答案 4 :(得分:4)

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

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

答案 5 :(得分:4)

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

答案 6 :(得分:4)

依赖注入

严格地说,依赖注入只不过是一个横切关注的问题。许多依赖注入框架使用基于属性的编程风格,如下所示:

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

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

答案 7 :(得分:3)

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

答案 8 :(得分:3)

在Java中不能有多重继承。但是,通过使用AOP,您可以拥有“有限”的多重继承。 试着谷歌这个看一些例子。

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

答案 9 :(得分:2)

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

答案 10 :(得分:2)

My photo album将aspectj用于三件事:

  1. Implementing the observer "pattern" as a reusable piece of code.
  2. Destroying a session for a specific type of call.
  3. Setting dirty flags on DTOs when mutation occurs.
  4. 第一个,尤其是google tech talk on AOP。它与大多数人所考虑的方式不同。如果你对如何使用它感兴趣,绝对建议观看。

答案 11 :(得分:2)

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

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

有关详细信息,请访问 http://montrealistic.blogspot.com/2011/08/aspect-oriented-implementation-of.html

答案 12 :(得分: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,模型中的代码对日志记录一无所知。它只关注业务逻辑。

答案 13 :(得分:1)

交易管理。

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