java - 建模事件类型对象

标签 java oop events

我们有一个由许多独立组件和子系统组成的应用程序。我们正在考虑实现一个简单的事件记录机制,其中这些组件和子系统可以记录一些感兴趣的事件。事件可能类似于

  • 已创建新帐户
  • 航类抵达
  • 每周报告发送给管理层等。

正如您所看到的,事件类型本质上是异构的,并且需要记录的属性根据事件类型而不同。例如,新帐户创建事件还将记录帐户 ID、创建新帐户的用户的姓名等。而航类到达事件将记录航类号、到达、来自等。

我想知道对事件类型和属性进行建模的好方法是什么。

一种选择是采用面向对象的方式 - 拥有一个具有一些公共(public)属性(时间戳、消息等)的 AbstractEvent,然后在下面创建完整的类层次结构。例如,飞行事件可能如下所示

abstract class AbstractEvent;
abstract class FlightEvent extends AbstractEvent;
class FlightArrivedEvent extends FlightEvent;
class FlightCancelledEvent extends FlightEvent;

我发现这种方法的问题是我们有数百个事件会导致类爆炸。另外,每当我们添加一个新事件(很可能)时,我们都必须创建一个类并将新包分发到所有组件和子系统。

我能想到的第二个选择是在光谱的另一端。有一个简单的 Event 类,其中包含基本属性并在其中包装一个映射,以便客户端可以填充他们想要的任何数据。这种情况下的代码将如下所示。

class Event {
    private timestamp;
    private eventType;
    private Map attributes;

    public Event ( String eventType ) {
        timestamp = System.nanoTime();
        this.eventType = eventType;
        attributes = new HashMap();
    }

   public Event add ( String key, String value ) {
        attributes.put ( key, value );
        return this;
   }
}
//Client code.
Event e = new Event("FlightEvent:FlightArrived")
         .add("FLIGHT_NUMBER", "ABC123")
         .add("ARRIVED_AT", "12:34");

虽然这很灵活,但它存在不一致的问题。两个组件可以以两种不同的格式(FLIGHT_NUMBER 和 FLGT_NO)记录 FLIGHT_NUMBER 键,我想不出强制执行某些约定的好方法。

有人有一些建议可以在这两个极端选项之间提供一个很好的折衷方案吗?

最佳答案

有一个 Java 事件框架(请参阅 java.util.EventObject 和 Beans 框架),但您提出的基本问题与事件无关。这是一个设计问题,就是:我是否在应用程序中使用 Java 类来表示我的业务领域中的类?

很明显,不同类型的事件是不同的事物“类”,但出于可维护性的原因,您正在考虑在映射中表示业务数据,以便不必编写和分发实际的类。如果您将其推向逻辑极端,您可以设计没有类的整个应用程序,而仅对所有内容使用映射和名称-值对 - 而不仅仅是事件。这将是一团糟,你将永远调试它,因为你将没有任何类型安全。查找 map 中内容的唯一方法是在某些文档中查找某人可能添加到其中的内容以及该对象可能是什么类型。

所以,事情是这样的 - 你实际上并没有摆脱你的类定义

您会将其移至 Word 文档中的某个位置,人们必须引用该位置才能了解 map 中的内容。 Word 文档需要维护、验证和分发,但与 Java 类不同,它不会由编译器检查,并且不能保证程序员会正确解释它。

所以我想说,如果有一个类,请将其放入代码中,然后专注于解决 Java 类的分发和版本控制问题,而不是 Word 文档的分发和版本控制问题。

我将再次提到版本控制,因为如果您可能序列化对象并恢复它们,这就是一个问题,因此您需要考虑这一点。

一些注意事项:

  1. 如果您正在编写一款将事件从一个系统路由到另一个系统的中间件软件,那么您可能不需要知道数据是什么,并且使用在这种情况下是通用支架。如果您不需要查看数据,则不需要它的类。

  2. 您可能会收到高级设计师和架构师的提示,提示类的数量以及与映射和名称/值内容相比,他们在定义类时必须做的工作。这是因为将类(即真正的设计)放入 Java 中比将它们放入 Word 文档中更困难。如果您是高水平的挥手型人,那么更容易在 Word 中编写一些空洞的东西,不需要运行甚至不需要编译,然后将真正的设计工作交给程序员来开始工作。

关于java - 建模事件类型对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29820434/

相关文章:

.net - .NET 中发生垃圾收集时是否有事件?

java - 跨越多个 WAR 的事务

java - 二叉搜索树实现中迭代器和泛型的困难

python - 在同一个类中定义之前使用另一个方法中的方法?

javascript - 如果Child组件动态组件,如何将数据从Child传递到Parent

powershell - 如何在 powershell 中发送鼠标点击?

java - 使用 JDOM2 构建 XML 并添加数据

java - 使用 SharedPreference 实现首选项,适用于 Android 动态壁纸

ruby 抽象

javascript - 构造函数中的订阅