面向方面编程有哪些可能的和关键的缺点?
例如:新手的隐秘调试(可读性影响)
答案 0 :(得分:10)
我认为最大的问题是没有人知道如何定义方面的语义,或如何非程序地声明连接点。
如果你不能独立于嵌入的上下文定义一个方面的作用,或者定义它所具有的效果,使它不会破坏它嵌入的上下文,你(和工具)无法推断它的可靠性。 (你会注意到方面最常见的例子是“logging”,它定义为“将一些东西写入应用程序不知道的日志流”,因为这是非常安全的)。这违反了David Parnas关于information hiding的关键概念。我看到的最糟糕的方面之一是将同步原语插入代码中;这会影响代码可能具有的交互顺序。你怎么可能知道这是安全的(不会死锁?不会活锁?不会失败保护?面对同步伙伴中抛出的异常可以恢复?)除非应用程序只做了一些微不足道的事情。
现在通常通过提供某种标识符通配符来定义连接点(例如,“将此方面放入名为”DataBaseAccess *“的任何方法中。为此,编写受影响方法的人必须表明他们的意图通过以有趣的方式命名代码来使代码变得具体化;这几乎不是模块化的。更糟糕的是,为什么一个方面的受害者甚至必须知道它存在?并考虑如果你只是重命名一些方法会发生什么;方面不再是在需要的地方注入,你的应用程序中断。我们需要的是故意的连接点规范;不知何故,方面必须知道它需要的位置而不需要程序员在每次使用时放置霓虹灯标志point。(AspectJ有一些与控制流相关的连接点,在这方面看起来好一些。)
因此,方面是一种有趣的想法,但我认为它们在技术上是不成熟的。而这种不成熟使他们的使用变得脆弱。这就是问题所在。 (我是自动化软件工程工具的忠实粉丝[请参阅我的简历],不是这样)。
答案 1 :(得分:8)
我认为最大的缺点是使用AOP。例如,人们在没有意义的地方使用它,并且不会在它所使用的地方使用它。
例如,工厂模式显然是AOP可以做得更好的事情,因为DI也可以做得很好,但是使用AOP时观察者模式更简单,战略模式也是如此。
单元测试会更难,尤其是如果你在运行时进行编织。
如果在运行时编织,那么你也会受到性能影响。
在将AOP与类混合时,有一个很好的方法来模拟正在发生的事情是一个问题,因为UML在那时我认为不是一个好的模型。
除非您使用Eclipse,否则工具确实存在问题,但使用Eclipse和AJDT AOP要容易得多。
我们仍然使用junit和nunit,因此必须修改我们的代码以允许单元测试运行,当使用特权模式时AOP也可以通过测试私有方法来做更好的单元测试,而且我们不必更改我们的程序只是为了让它们与单元测试一起工作。这是另一个没有真正理解AOP如何有用的例子,我们仍然通过单元测试框架和当前设计模式实现以多种方式链接到过去,并且没有看到AOP如何帮助我们做更好的编码。
答案 2 :(得分:7)
答案 3 :(得分:7)
维护和调试。使用aop,你突然拥有在给定点运行的代码(方法入口,退出,无论如何),但只是查看代码,你不知道它甚至被调用,特别是如果aop配置在另一个文件中,像xml配置。如果建议导致一些更改,那么在调试应用程序时,事情可能看起来很奇怪,没有任何解释。这不仅仅影响新手。
答案 4 :(得分:2)
我不认为这是一个关键的劣势,但我看到的最大问题是开发人员的经验和适应能力。并非所有开发人员都了解声明式编程和命令式编程之间的区别。
我们非常广泛地使用了EntLib 4.1中的policy injection application block以及用于DI的Unity,而对于某些人来说,它并不是很快就会陷入困境。我发现自己一遍又一遍地向同一个人解释为什么应用程序没有按照预期的方式运行。它通常从他们解释的东西开始,我说“看到方法上面的声明。” :)有些人马上得到它,喜欢它并变得非常富有成效 - 其他人也在努力。
学习曲线并非AOP独有,但它似乎比普通开发人员遇到的其他事情具有更高的学习曲线。
答案 5 :(得分:0)
关于维护/调试参数,面向方面的编程往往与敏捷软件开发实践的所有其他方面齐头并进。
这些做法倾向于从图片中删除调试,将其替换为单元测试和测试驱动开发。
此外,通过建议而不是没有建议的大型,难以理解的代码占用空间来维护一个小而清晰的代码占用空间可能要容易得多(建议是将大的,难以理解的代码占用空间转换为小而清晰的代码)足迹)。
答案 6 :(得分:0)
因为AOP的力量,如果你的横切有一个错误,它可能会导致广泛的问题。另一方面,有人可能会改变程序中的连接点 - 例如,通过重命名或移动方法 - 以方面编写者没有预料到的方式,会产生意想不到的后果。模块化横切关注点的一个优点是使一个程序员能够轻松地影响整个系统。