首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >事件类型对象建模

事件类型对象建模
EN

Stack Overflow用户
提问于 2015-04-23 10:15:57
回答 2查看 85关注 0票数 0

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

  • 创建新帐户
  • 航班到了
  • 每周向管理层提交报告等。

如您所见,事件类型本质上是异构的,需要记录的属性因事件类型不同而不同。例如,新帐户创建事件还将记录帐户id、创建新帐户的用户的名称等。而“到达”事件将记录航班号、到达或到达等。

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

一种选择是以面向对象的方式实现它--拥有一个具有一些公共属性(时间戳、消息等)的AbstractEvent,然后在下面创建一个完整的类层次结构。例如,飞行事件看起来就像

代码语言:javascript
运行
复制
abstract class AbstractEvent;
abstract class FlightEvent extends AbstractEvent;
class FlightArrivedEvent extends FlightEvent;
class FlightCancelledEvent extends FlightEvent;

我看到的问题是,我们有数百起事件,将导致班级爆炸。此外,每当我们添加一个新事件(很可能),我们就必须创建一个类,并将新的包分发到所有组件和子系统。

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

代码语言:javascript
运行
复制
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密钥以两种不同的格式(FLIGHT_NUMBER & FLGT_NO)记录下来,我想不出一种好的方法来强制执行某些约定。

任何一个人有一些建议,可以提供一个很好的折衷这两个极端的选择?

EN

回答 2

Stack Overflow用户

发布于 2015-04-23 10:46:22

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

显然,不同类型的事件是不同的“类”,但出于可维护性的原因,您正在考虑在地图中表示业务数据,这样就不必编写和分发实际的类。如果您将这一点带到一个逻辑的极端,您可以设计没有类的整个应用程序,只需使用映射和名称-值对来处理所有事情--而不仅仅是事件。这将是一个混乱,你将永远调试它,因为你将没有任何类型的安全。查找地图中的内容的唯一方法是在某个文档中查找某个人可能添加到其中的内容以及该对象的类型。

所以,事情是这样的----实际上您不可能摆脱类定义

你会把它移到一个文字文档的某个地方,人们将不得不参考,以了解什么是在你的地图。Word文档需要维护、验证和分发,但与Java类不同的是,编译器不会检查它,也不能保证程序员会正确地解释它。

所以我想说,如果有一个类,把它放在您的代码中,然后专注于解决分发和版本化Java类的问题,而不是分发和版本化Word文档。

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

一些注意事项:

  1. 如果您正在编写将事件从一个系统路由到另一个系统的中间件软件,您可能不需要知道数据是什么,在这种情况下使用泛型持有者可能是有意义的。如果不需要查看数据,则不需要为其设置类。
  2. 您可能会收到高级设计人员和架构师的抱怨,抱怨与地图和名称/值的内容相比,类的数量以及在定义类时必须做的工作。这是因为在Java中放置类(即真正的设计)比将它们放在Word文档中要困难。如果你是一个高水平的挥手型的人,你就更容易写出一些不需要运行甚至编译的词,然后把真正的设计工作交给程序员去完成。
票数 1
EN

Stack Overflow用户

发布于 2015-04-23 10:30:07

有人能在这两种极端选择之间提供一个很好的折衷方案吗?

不是的。对于这个问题,没有通用的一刀切的答案。你必须找到一个平衡,适合你的产品的总体设计。如果你把每件事都搞清楚了,你将需要成千上万的课程。如果你给了很大的回旋余地,你可以逃脱一些,但你是在用精确的方式来支付你的自由。请看我的博客"设计垃圾箱

您有共享属性吗?就像这样:您是否希望像现在这样用非常贴合的语义来定义事件的属性?

这意味着您有一个简单的事件和类型的属性(也就是说,String value是不够的)。您需要对属性进行格式化和验证,或者..。属性本身需要是类。

如果是这样的话,可以使用我的类型安全映射模式:http://blog.pdark.de/2010/05/28/type-safe-object-map/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29820434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档