事件通知:Java设计模式

时间:2014-04-11 19:33:19

标签: java design-patterns

我正在开发一个有几个模块的项目。我有一个位于底座的模块,它对所有模块都是通用的。 我在基本模块中有一个业务对象(这是单例类),这可以触发事件完成的事件。

我希望每个模块都能听到这个事件并做一些具体的事情。

这样做的最佳方式是什么?

公共模块是在应用程序启动时执行的第一个代码,因为它是基础,它不能调用它上面的模块。

编辑: 考虑到我的情况,我认为这个问题有点不完整。以下是解释。

我有一个单例类(我把它作为不可变的)。该类存在于基本模块中。它有一个静态方法getInstance(),它将根据存储在表中的数据初始化一个新对象。 有一个后台调度程序,它将使用来自服务器的最新数据定期更新该表中的数据。目前我正在做的是调度程序直接与表进行交互。 1.我不希望任何外部访问该数据。我想在单例类中提供静态方法,如

protected static void doPeriodicUpdate() {
}

从后台调度程序中调用此方法,如

MySingleTonClass.doPeriodicCheck();

有一种静态方法的好方法吗?

单例类可以随时触发一些事件,如

1. MyEventOne
2. MyEventTwo

正在侦听这些事件的侦听器将获得mysingletonclass对象的句柄,并将执行某些特定功能。创建此对象后,它将仅在tomcat关闭时销毁。在tomcat启动时,我有一个init servlet,它初始化这个singleton对象并将它放在servlet上下文中,这样任何想要这个对象的类都可以访问它。 当事情发生时将触发这些事件,之后我必须更新表。为此,我计划在单件类中使用静态方法,如

protected static void doSomething(String arg0) {
     // This will do something on database
     // After completion
     fireMyEventOne();
}

// Something happened at client side. Client will call the rest service and rest service will call static method like

class MyRestService extends MySingleTonClass {
      MySingleTonClass.doSomething();
}

像这样,可能会有其他事件在客户端发生其他事件时可以触发。客户将以相同的方式呼叫休息服务。

我觉得这种方法有问题。任何建议都将受到高度赞赏。

1 个答案:

答案 0 :(得分:4)

查看Google's Guava library中包含的活动总线。它的设计几乎完全适用于您的用例:应用程序的一部分触发事件,而另一部分订阅这些事件,而这两个部分不必彼此了解(如果您通过以下方式解决它,通常就是这种情况)在基础模块上注册外部模块的事件处理程序。)

我认为他们的例子很好地体现了使用图书馆的感受:

// Class is typically registered by the container.
class EventBusChangeRecorder {
    @Subscribe public void recordCustomerChange(ChangeEvent e) {
      recordChange(e.getChange());
    }
}

// somewhere during initialization
eventBus.register(new EventBusChangeRecorder());

// much later
public void changeCustomer() {
    ChangeEvent event = getChangeEvent();
    eventBus.post(event);
}

在您的情况下,您的基本模块将是发布到事件总线的部分,而其他模块将使用@Subscribe注释的方法。您需要确保的是模块可以共享事件总线的一个实例,例如,您可以在基本模块中创建它,然后允许其他模块访问它。