跨领域关注示例


120

一个很好的例子是cross-cutting concern什么?维基百科页面上的病历示例对我而言似乎并不完整。

特别是从此示例中,为什么日志记录会导致代码重复(散射)?(除了像log("....")到处这样的简单调用之外,这似乎没什么大不了的)。

a core concern和a和有cross-cutting concern什么不一样?

我的最终目标是更好地了解AOP。

Answers:


234

在了解“ 横切关注点”之前,我们必须先了解“ 关注点”

关注的是,是指系统的功能的基础上划分的一部分的术语。

关注分为两种类型:

  1. 代表主要需求的单个和特定功能的关注点称为核心关注点

    系统的主要功能被称为核心问题。
    例如:业务逻辑
  2. 表示次要功能的关注点称为横切关注点或系统范围的关注点
    OR
    横切关注点是关注它适用于整个应用程序,它会影响整个应用程序。
    例如:日志记录,安全性和数据传输是几乎每个应用程序模块都需要的关注点,因此它们是跨领域的关注点。

礼貌

在此处输入图片说明

该图代表了一个细分为模块的典型应用程序。每个模块的主要关注点是为其特定领域提供服务。但是,每个模块还需要类似的辅助功能,例如安全日志记录和事务管理。横切关注点的一个示例是“日志记录”,它经常在分布式应用程序中使用,以通过跟踪方法调用来辅助调试。假设我们在每个函数体的开头和结尾都进行日志记录。这将导致横切所有具有至少一个功能的类。

(礼貌)


1
“横切关注点是适用于整个应用程序的关注点”➤对此不确定,因为事务管理不适用于“整个”应用程序,但仍是横切关注点。而图片告诉我什么是诚实的,它只是混淆..
科瑞图加伊

很好的解释,但是我对我们称之为“这些关注点”的图片有一点问题,横切关注点不是横切关注点,我认为最好用横切关注点消除其他关注点,而不是另辟way径。像面向方面的开发一样
hyeganeh

得到的答案仍然不会简单地使用类似的Log4j和记录像LogManager.getLogger()解释该问题的信息(模块名,味精)。
玉萍辛格

49

我认为,跨部门关注的最佳例子就是交易行为。例如,必须在所有服务方法中都放置带有提交和回滚调用的try-catch块,这会令人反感。用标记注释方法,AOP可以使用这些标记将其封装为所需的交易行为,这是一个很大的胜利。

授权是跨领域关注的另一个很好的候选人。与在服务方法代码中处理标记相比,用标记来标记服务方法,该标记可以告诉谁可以调用它,并让一些AOP建议决定是否允许该方法调用。

使用AOP建议实施日志记录可能是获得更大灵活性的一种方式,因此您可以通过更改联接点来更改记录的内容。在实践中,我看不到项目经常这样做。通常使用log4j之类的库,使您可以根据日志记录级别和类别进行过滤,如果需要,可以在运行时很好地解决问题。

核心问题是应用程序存在的原因,即应用程序自动化的业务逻辑。如果您有一个物流应用程序来处理货运,那么弄清楚您可以在卡车上装多少货物,或者卡车下车的最佳路线是什么,这可能是核心问题。跨部门关注点通常是实现细节,需要与业务逻辑分开。


2
因此,即使事务行为实际上仅存在于数据访问层中,但由于try-catch块在许多方法中都是重复的,因此被认为是跨领域的。我最初的理解是交叉切割意味着代码跨越了应用程序的多层。
jlars62 2014年

4
@ jlars62:横切表示它与要素成直角。
内森·休斯

7
@ jlars62:我的意思是直角:将要素视为一叠图层。横切关注点可能仅适用于一层,但对所有要素都是通用的。
内森·休斯

@NathanHughes授权是一个很好的例子。我刚刚重构了我的应用程序,将所有授权代码都放在了跨领域的体系结构中,它为清除大量代码带来了奇迹。我认为该域就像一所房子。如果您有进入的钥匙,则可以在其中进行任何操作(假定您是所有者)。但是您不会锁住房子的每扇门并要求输入钥匙。您正在或不在。
理查德

“交易行为”可能是许多功能部件所共有的,但这并不是“交叉切割”,因为它不是“交叉”层。例如,日志记录是一个跨领域的问题,是因为我可能想登录表示层,业务层,数据层等
。– CodingYoshi

14

除了已接受的答案外,我还要提及另一个涉及跨领域的问题:远程处理。假设我只想在本地调用我的生态系统中的其他组件,就像它们在运行一样。也许在某些情况下,他们甚至这样做。但是现在我想在云或群集中运行我的服务。作为应用程序开发人员,我为什么要关心这方面?一个方面可以照顾到找出呼叫者和呼叫方式,并在必要时对传输的数据进行序列化并进行远程呼叫。如果一切都在进行中,则方面将只转发本地呼叫。在被叫方,方面将反序列化数据,进行本地呼叫并返回结果。

现在,让我告诉您一个有关日志输出等“琐碎”事情的小故事:就在几周前,我为客户端重构了一个复杂但不太大的代码库(大约25万行代码)。在数百个类中,使用了一种日志记录框架,在另外数百个中,使用了一种。然后有几千行System.out.println(*)真正应该有日志输出的地方。因此,我最终修复了分散在整个代码库中的数千行代码。幸运的是,我可以在IntelliJ IDEA(结构化搜索和替换)中使用一些巧妙的技巧来加快整个操作的速度,但是,男孩,您不认为这很简单!当然,与上下文密切相关的调试日志记录肯定会始终在方法主体中发生,但是许多重要的日志记录类型,例如跟踪方法调用(甚至分层地显示缩进的输出),记录已处理或未处理的异常,用户审核(记录对基于用户角色的受限方法等)可以轻松实现,而又不会污染源代码。日常应用程序开发人员无需考虑它,甚至无需查看遍布整个代码库的记录器调用。

对于其他跨领域问题,我可以提出类似的解释。保持代码整洁并避免IMO的散乱和缠结是专业问题,而不是可选的问题。最后但并非最不重要的一点是,它使代码保持可读性,可维护性和可重构性。阿们


0

横切关注点是始终存在的场景,无论应用程序的类型如何。

例如日志记录,安全性,性能分析,本地化,可访问性,事务处理等。无论我们要构建的软件是什么,都需要日志记录(否则,有人将如何调试产品或从产品数据中获取一些相关信息)。只有只有可靠的用户才能使用正确的特权集进入应用程序,才需要安全性(身份验证/授权等)。我们需要知道您的应用程序如何执行,然后需要进行性能分析。如果国际用户使用应用程序(使用他们自己的本地化语言),那么我们需要在应用程序中支持该应用程序。可访问性是残疾人使用我们的应用程序的可用性案例。

现在,无论我们的应用程序是基于桌面,基于Web的应用程序,还是如果最终用户都需要在生产环境中跨地区使用它,那么都需要交叉使用。到目前为止,我还没有透露有关应用程序的全部内容,但给出了在生产环境中将其发布给最终用户之前应解决的问题列表。而这全都涉及交叉问题(所有应用程序/方法/类都需要处理,即在各个级别上)。

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.