欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

事件不会消除依赖性

程序员文章站 2024-03-23 10:18:34
...

事件(或消息)驱动的系统(具有两种风格 )具有一些好处。 我已经讨论了为什么我认为它们被过度使用了 但这不是我现在要写的。

我将(非常简短地)写有关“依赖关系”和“耦合”的文章。 似乎当我们消除编译时依赖性时,我们消除了组件之间的耦合。 例如:

class CustomerActions {
  void purchaseItem(int itemId) {
    //...
    purchaseService.makePurchase(item, userId);
  }
}

class CustomerActions {
  void purchaseItem(int itemId) {
    //...
    queue.sendMessage(new PurchaseItemMessage(item, userId));
  }
}

看来您的CustomerActions类不再依赖于PurchaseService 不管谁将处理PurchaseItem消息。 当然会有一些PurchaseService处理消息,但是前一类在编译时并没有绑定。 这看起来像是“松散耦合”的一个很好的例子。 但事实并非如此。

首先,这两个类可能首先是松散耦合的。 一个与另一个交互的事实并不意味着它们是耦合的-只要PurchaseService保持其makePurchase方法的合同,它们就可以*地独立更改。

其次,消除了编译时依赖性并不意味着我们消除了逻辑依赖性。 事件已发送,我们需要一些东西来接收和处理它。 在许多情况下,这是同一VM /部署中的单个目标类。 *的文章定义了一种根据数据衡量耦合的方法 上面两种方法有什么不同? 否-在第一种情况下,我们将不得不更改方法定义,在第二种情况下,我们将更改事件类定义。 而且,我们仍然有一个处理类,在更改合同后,我们可能还必须更改其逻辑。 在某种程度上,即使在编译时未明确实现,前一类仍然在逻辑上依赖于后者。

关键是,逻辑耦合仍然存在。 仅将其移至事件中并不能带来“应许”的好处。 实际上,它使代码更难以阅读和跟踪。 在前一种情况下,您只是简单地向IDE请求一个呼叫层次结构,而跟踪谁产生和谁使用给定消息则可能比较困难。 事件方法有一些优点-事件可以推送到队列中,但可以直接调用(例如,通过代理,例如spring仅使用一个@Async批注)。

当然,这是一个简化的用例。 更复杂的应用程序将从事件驱动的方法中受益,但是在我看来,这些用例很少涵盖整个应用程序体系结构。 它们通常更适合于特定问题,例如NIO库。 我将继续保留这一常识性口头禅–不要做任何事情,除非您知道它给您带来的好处是什么。

翻译自: https://www.javacodegeeks.com/2015/08/events-dont-eliminate-dependencies.html