除了面向方面的编程之外,还有什么替代方法可以解决交叉问题?[关闭]


19

面向方面的编程有望解决跨领域的问题,但是我还没有完全了解它。是否有其他尝试来解决这个问题?


访客模式可以解决许多情况,现在可以通过AOP解决。
史蒂文·埃弗斯

@SnOrfus:另请参阅下面的响应,在此我讨论Java的DJ库:一种使用访客模式的动态方式!值得一试。(这也是可以与Reflection一起使用的常规技术。)
Macneil,2010年

Answers:


7

如果可能,您可以将横切关注点封装到单独的模块中,然后通过依赖关系注入在整个应用程序中使用。这使您能够在某种程度上将跨领域关注实现与其在整个代码中的使用脱钩。

但是,这并不总是优雅地工作。这就是人们尝试使用AOP之类的方法解决该问题的原因。


6

我还没有发现的另外两个选择:

使用Monad和箭头进行功能编程

在FP中,您像其他任何事物一样代表了一个跨领域的关注点:在函数调用中传递某些东西。由于这样做显然很乏味,因此您可以使用Monads(或Arrows)来隐藏传递的额外信息。

最常见的AOP示例是日志记录。使用Monads,您将创建一个“记录器” monad,以保留消息列表。您通过LoggerMonad执行的所有功能都可以发布日志消息。使用Arrows,您可以对应用程序的整个数据流进行建模,并在适当的情况下将日志记录例程纳入模型。我认为。箭头很复杂。

基于实体/组件的编程

我一直在研究和试验游戏引擎。您可以将所有内容分解为在一种类型的组件上运行的数据(组件)和服务的数据包,而不是像OOP中的“对象”。组件通过通用ID分组在一起,例如在关系数据库中,而链接的组件组就是实体。要在这样的系统中添加日志记录,您可以根据要通过哪些组件来向触发器添加新的日志记录服务。

两种方法都可以很容易地轻松完成跨领域的更改,但是这两种方法都是高级架构模型。因此,您可能需要从一开始就使用它们。从理论上讲,组件模型可以在现有的OOP系统中使用。我想如果您的语言足够强大,monads也可以。


当谈论Monads和Arrows时,您还应该提及Applicative Functor。
Waquo 2011年

3

有几种方法可以解决横切关注的问题:

  • 使用更好的设计模式,惯用语或抽象机制:即使代码可以模块化,也可能是横切的。为了维护代码,您将需要重构以使用可以对其进行模块化的设计技术。这样的重构可能会引入其他类型的横切,但是希望哪些横切是稳定的,并且不太可能改变。

  • 开发更丰富的语言功能:可以通过更好的抽象机制解决横切的许多表现形式,有时还需要新的语言功能。例如,包含功能和面向对象功能的更高级的语言通常不需要使用那么多的设计模式,因为它们不是必需的。请注意,设计模式本身在本质上可能是横切的,因为它们描述了几种不同对象和类的角色。在Java中,尽管运行时成本较高,但通常可以使用反射来代替方面。例如,使用反射,只需几行代码就可以支持数百个类的访问者模式。DJ资料库Northeastern的解决方案就是这样做的一种反射解决方案。Mixins是C ++(而不是Java)可用的强大技术,可以作为方面为您提供一些相同的用例。

  • 提供更好的工具支持:使用grep和执行重构操作等技术可以处理与横切代码相关的问题。例如,在接口中声明的方法的名称可以贯穿整个程序。(请注意此处的技术差异:横切线是方法的名称,而不是方法的实现。)在像Eclipse这样的IDE中,这通常不是问题,您可以在其中使用“重命名重构”来更改所有代码中使用该名称的位置。这样,当编程环境对您来说足够表达时,可能不需要语言功能。

  • 使用特定领域的语言:早于AspectJ的早期方面的语言是特定于领域的,仅应用于某些问题,例如线程同步或数据流分析,以有效地组合功能组合。这些语言是实验性的,但在模块化关注问题方面似乎非常成功,而这些问题原本是横切的。

  • 使用生成式编程技术:升级到元级别可能被认为是面向方面的编程的一种实现技术,但是它足够大,可以超越简单的方面。生成技术(其中一个程序为另一个程序生成源代码)也与特定领域的语言有关。

对于所有这些,我认为学习AOP是适当的。即使您不使用AOP语言,AOP也会帮助您扩展代码的概念。


2

通常,使用声明性功能标记代码元素,尤其是C#/。NET / Mono世界中的Attribute系统。


你可以说得更详细点吗?您所描述的是某些AOP系统如何工作。
史蒂文·埃弗斯

2
这几乎是AOP。
Matt H

AOP在其典型/经典意义上需要大规模的支持工具(编织IDE的一个方面)。AOP使得仅凭原始源代码就很难推理代码。当纵横僵尸渗透到您的程序时,很难预测组件的行为。属性或标记提供类似的功能,但在源代码中具有显式表示。

请注意,我的问题并不完全与AOP方式解决的问题有关。我唯一关心的是,使用AOP时,我的源代码不足以预测程序的行为。

@mumtaz:我可以看到将方面应用于整个名称空间时的情况。AOP的另一种方法:归因方法/属性/等。将方面应用到其上,与您所描述的相同。
史蒂文·埃弗斯

2

我不是AOP方面的专家,但是经过多年的阅读,它一直看起来像Lisp提供元编程的一种较弱形式,尤其是它的元对象协议之类的部分。

我想这不足为奇:Gregor Kiczales是AMOP的作者之一,后来写了Java的AspectJ!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.