面向方面的编程实例
一种产品,其贷款的例子直接从这个Aspect Oriented Programming: Radical Research in Modularity, Youtube video被画到显示器。在这个例子中,你有一个绘图程序,它由点,形状等组成,当这些对象发生变化时,你需要告诉显示器自行更新。没有在一个方面处理它,你最终会重复一下自己。
正如我所了解的那样,AOP的创建是为了不重复自己,因为它可能与业务逻辑没有任何关系。通过这些方面,您可以将这些担忧模块化。其中一个例子是日志记录,但有很多不同的事情可能最终会重复。它一直在发展,它不再是面向方面的编程,而是面向方面的建模。
约面向方面的编程的更多信息可以从这些来源中找到:
- 改为:
- 听:
- 看:
安全性 - 在执行某些方法之前检查用户是否具有适当的权限。
公共不变量检查。由于PostSharp 1.5将带有方面继承,即使通过接口,它也会带来很多新的机会。
安全
-
,检查权限和阻止访问
更友好的错误封邮件的asp.net器WebControls
-
,捕捉异常和写入堆栈跟踪时
- 注入代码错误编译时的调试编译或友好的消息(如这里的东西:Transparent generic exception handling for asp.net/MOSS2007 (with code))
性能
- 注入代码,设置PERF的计数器来获取您的应用程序很慢
验证的概述:
[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; }
用Java和AspectJ(和Hannemann的Kiczales)设计模式实现: http://www.cs.ubc.ca/labs/spl/papers/2002/oopsla02-patterns.pdf
本文介绍如何某些GoF的设计模式可以使用AspectJ
你不能在Java的多重继承Java中的一个更好的办法来实现。但是通过使用AOP,你可以“有限”多重继承。 尝试谷歌这看到一些例子。
我也同意Eyvid。 Hannemann和Kiczales的论文非常适合学习设计模式的基础知识并获得一些很好的AOP示例。
My photo album使用AspectJ的三两件事:
- Implementing the observer "pattern" as a reusable piece of code.
- Destroying a session for a specific type of call.
- Setting dirty flags on DTOs when mutation occurs.
第一,特别是相当多直出google tech talk on AOP的。它的模块化方式与大多数人所考虑的方式不同。绝对推荐观看,如果你有兴趣如何使用它的好。
另一个经典的例子(如日志记录)是缓存。但其他例子更有趣。
撤消 - 我打电话给支持撤消操作的第三方程序集。它要求调用者创建一个撤消上下文,调用程序集中的一些方法,然后销毁撤消上下文。上下文可以嵌套。此外,如果上下文已创建,但仍处于需要重新启动应用程序的不受欢迎状态。
通常使用撤消我会写这样的事情
void foo()
{
int id = lib.create_undo_context();
try
{
lib.performsomeaction();
lib.performsomeaction();
lib.performsomeaction();
}
finally
{
lib.destroy_undo_context(id);
}
}
与PostSharp我定义一个名为[撤消]属性,创建方法开始时撤消背景和毁坏它,当方法退出(即使抛出一个异常) - 使代码看起来像这样
[Undo]
void foo()
{
lib.performsomeaction();
lib.performsomeaction();
lib.performsomeaction();
}
这是一个更复杂一点实现这个比我展示,因为我已经确保所有撤消上下文,即使在有嵌套撤消的情况下被清理上下文 - 但你明白了。
交易管理。
在我看来,您不希望可能属于交易一部分的对象知道它们处于交易中。使用AOP,您可以根据需要将对象组合到事务中,而无需事务中的对象知道事务处于事务中,甚至不需要知道事件是否存在于AOP框架中。
我已经使用了面向方面的编程来实现关键字搜索引擎。它更像是一个实验,但它显示了AOP如何用于记录和跟踪以外的目的。
基本上:
(i)所述发动机的用户标记他/她的类作为KeywordSearchable,
(ⅱ)发动机开始跟踪创建&破坏这些KeywordSearchable实例,
(ⅲ)所述的发动机的萃取来自这些KeywordSearchable对象的关键字,
(iv)给定对象和关键字,算法负责搜索。
关于此的更多详细信息可在http://montrealistic.blogspot.com/2011/08/aspect-oriented-implementation-of.html找到。
依赖注入
严格地说,依赖注入只不过是一个横切关注点更多。很多依赖注入框架使用基于属性的编程式是这样的:
public class Car:IDisposable
{
[Inject]
public IGearBox Gearbox { get; set; }
...
}
的〔进样]属性也可以设计成没有任何依赖于外部框架的一个方面。 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时,模型中的代码对于日志记录一无所知。它将专注于业务逻辑。
de方面在哪里? 但是,您可以使用一些建议来阅读来自点提供的连接点的此“注释”,如: * * save(..) 因此,如果需要,您可以使用before建议进行验证并继续进行,或者抛出一些关于无效状态的失败条件。 – paulosuzart 2008-11-28 12:37:23
这取决于验证的使用位置以及使用的是哪种UI框架。我不会将这些方面用于需要验证的实体,而更多用于“防御性编码”。我不使用存储库中保存方法的实体验证,但是我在UI中的某处进行了验证。 – Paco 2008-11-28 19:50:29