观察者设计——如何访问method.invoke作用域?
我目前有一个Java Observer/Observable 设置,其中我打开Observer.update 的Object 参数中的某些字段(例如事件ID)来确定如何处理Observable 通知。
这会创建冗长的代码,例如:
public void update (Observable o, Object arg) {
if (arg instanceof Event) {
switch (((Event)arg).getID()) {
case EVENT_TYPE_A:
// do stuff...
break;
case EVENT_TYPE_B:
// do stuff...
break;
case EVENT_TYPE_C:
// do stuff...
break;
}
}
}
来自 ActionScript 背景,这对我来说感觉不必要的冗长...我宁愿传递一个由 Observable 直接调用的回调方法,而不是传递一个观察者的实例(更具体地说,由子类)。但是,我不清楚如何确定应调用该方法的对象(“拥有”该方法的类实例)。
我可以传递对包含该方法的实例的引用,但这听起来像是糟糕的 OOP。
我是不是找错树了?或者有没有一种干净的方法来实现这一目标?
i currently have a Java Observer/Observable setup in which i switch on some field within the Object parameter of Observer.update (e.g. event id) to determine how to handle an Observable notification.
this creates verbose code like:
public void update (Observable o, Object arg) {
if (arg instanceof Event) {
switch (((Event)arg).getID()) {
case EVENT_TYPE_A:
// do stuff...
break;
case EVENT_TYPE_B:
// do stuff...
break;
case EVENT_TYPE_C:
// do stuff...
break;
}
}
}
coming from an ActionScript background, this feels unnecessarily verbose to me...instead of passing an instance of an Observer, i'd prefer to pass a callback method to be called directly by the Observable (more specifically, by a subclass). however, i'm not clear how to determine the object on which the method should be invoked (the class instance that 'owns' the method).
i could pass a reference to the instance enclosing the method, but this smells like bad OOP.
am i barking up the wrong tree? or is there a clean way to achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这可能有点离谱,但由于 Java 5 及更高版本有泛型,传统的观察者和侦听器模式似乎都有点过时了。也就是说,类型是当今 Java 的常用语言。具有整数 ID 的事件的存在主要是因为针对常量的 switch 语句非常高效 - 以牺牲可读性为代价,并且通常需要强制转换来执行任何有用的操作(您可能知道,如果 ID = 23,则对象必须是 MouseEvent,但它更好如果您让编译器和运行时类型信息为您处理此问题,则更安全)。在现代 JVM 中的现代机器上,效率可能不值得。
因此,如果您没有结合 ID 和传统的观察者模式,您可能会考虑这样的事情:
这让我们(字面意思)成为一个通用的事件观察者;我们像这样打开传入对象的类型:
生成的代码(稍微)效率较低,但编写这样一个“观察者”的子类具有无限的可读性。它看起来不太像传统的观察者模式,但功能上是等效的。
如果您仍然需要额外的“事件”参数,您可以执行类似的逻辑来对两种类型进行参数化。
This may be a little far out in left-field, but since Java 5 and up have generics, both the traditional observer and listener patterns seem a little bit dated. That is to say, types are the lingua-fraca of java these days. Events with integer IDs exist principally because switch statements against constants are extremely efficient - at the expense of readability and often requiring casts to do anything useful (you may know that if the ID = 23, the Object must be a MouseEvent, but it is nicer and safer if you let the compiler and runtime type information take care of this for you). On a modern machine in a modern JVM, the efficiency may not be worth it.
So, if you are not married to IDs and the traditional observer pattern, you might consider something like this:
This gets us (literally) a generic Observer of events; we switch on the type of the object passed in like this:
The resulting code is (marginally) less efficient, but writing a subclass of such an "observer" is infinitely more readable. It does not look much like the traditional observer pattern, but is functionally equivalent.
If you still need an additional "event" parameter, you can just do similar logic to parameterize on two types.
更清晰的实现将涉及将事件是否可以由观察者/可观察对象处理的逻辑删除到实际观察者/可观察对象本身。看起来 ActionScript 给您留下了一个关于观察者模式的有趣想法。观察(无双关语):
A cleaner implementation would involve removing the logic of whether the event can be handled by the observer/observable, to the actual observer/observable itself. It appears as if ActionScript has left you with a funny idea about the Observer pattern. Observe (no-pun-intended):