8

我正在做一个项目,我们在 AssemblyInfo.cs 中有几个属性,这些属性被多播到特定类的方法。

[assembly: Repeatable(
AspectPriority = 2,
AttributeTargetAssemblies = "MyNamespace",
AttributeTargetTypes = "MyNamespace.MyClass", 
AttributeTargetMemberAttributes = MulticastAttributes.Public,
AttributeTargetMembers = "*Impl", Prefix = "Cls")]

我不喜欢这一点,它在 AssemblyInfo 中加入了一段逻辑(Info,请注意!),对于初学者来说,它根本不应该包含任何逻辑。最糟糕的是,实际的 MyClass.cs 在文件中的任何位置都没有该属性,并且完全不清楚此类的方法是否具有它们。从我的角度来看,它极大地损害了代码的可读性(更不用说过度使用 PostSharp 会使调试成为一场噩梦)。尤其是当您有多个多播属性时。

这里的最佳做法是什么?有没有人在使用这样的 PostSharp 属性?

4

2 回答 2

13

让我首先回答 Max:确实,方面不是好的 OOP 模式的替代品。它们是互补的。任何好的 AOP 设计都是从好的 OOP 设计开始的。但是 OOP 模式有时会迫使您手动编写大量的管道代码。对于这些情况,方面可以用于自动化OOP 模式的实现,而不是替换它们。

当您智能地使用 AOP 时,您的解决方案可以变得更易于理解(业务代码不与维护代码混合)、测试(您可以独立于业务代码测试方面,即您不必测试任何业务方法跟踪正确),更改(当您想要更改模式时,您只需要更改方面,而不是更改模式的每个实现)。现在,如果您滥用 AOP,如果您将其用作黑客工具,如果您以前不考虑 OOP 模式,那么您从 AOP 中获得的成本将超过收益。作为任何利器,AOP 应该被聪明地使用。

回到最初的问题。

谁告诉您应该将方面放在 AssemblyInfo.cs 中?您可以创建一个名为 GlobalAspects.cs 的新文件并将所有程序集级别的方面都放在那里。没错,AssemblyInfo.cs 应该只用于程序集级元数据。

但是像你一样,我不喜欢汇编级别的方面。我认为应该避免。汇编级方面的主要问题是它们依赖于命名约定,这是邪恶的。(这种邪恶在学术 AOSD 社区中被称为切入点脆弱性。)确实,当您重命名一个类或命名空间时,您更改了方面适用的方法集,这很快就会变成一场噩梦。这就是为什么我从不为自己使用基于命名约定的方面。

代码可读性如何?在很大程度上,我认为可读代码是短代码。如果我有一个名为 CreateProduct 的业务方法,我可能只想查看创建产品的代码。大多数时候,我对处理事务、异常或跟踪的代码不感兴趣。如果我知道某些方面可以为我处理就足够了。

我怎么知道?使用 PostSharp,您就拥有了 Visual Studio 扩展。使用 AspectJ,您就拥有了用于 Eclipse (AJDT) 的 AspectJ 插件。它们在 IDE 中向您展示了哪些方面应用于您当前看到的代码。如果你真的想看细节(但你很少真的想看),你可以使用调试器进入切面,或者使用 Reflector 查看生成的代码。

概括:

  1. 好的 AOP 设计总是从好的 OOP 设计开始的。
  2. 避免依赖命名约定来应用方面。
  3. 使用 Visual Studio 或 AJDT 的 PostSharp 扩展来可视化代码中的各个方面。
于 2010-03-22T07:32:06.120 回答
0

我敢肯定这将是一个不受欢迎的答案,但也许我可以得到我的同伴压力徽章......

你的直觉是正确的。将逻辑放入任何类型的元数据中都是一种可怕的、可怕的罪恶,人们会因此而在不可维护的地狱之火中永远燃烧。

我的意思不是不尊重这一点,尽管我确信它会被解释为其他方式。

最好的做法是不使用“面向方面的编程”工具,这些工具是使糟糕的设计和测试实践变得跛足的拐杖。相反,看看你的设计并问自己“为什么”。

为什么我觉得有必要使用这个工具?我试图解决什么设计问题?

一旦你牢牢抓住了问题,就去学习设计模式解释(Shalloway 和 Trott)或Head First Design Patterns(Freeman、Robson、Bates 和 Sierra)。

最后,面向模式的解决方案将更容易理解、更容易测试和更容易改变。唯一的额外成本将是掌握设计模式的一次性费用,而不是每次进行更改时试图弄清楚所有这些方面在哪里、它们如何组合在一起以及它们如何相互影响的经常性费用。

于 2010-03-22T06:22:16.440 回答