回调/命令与事件监听器/观察者模式
我正在尝试设计一个异步框架,并想知道人们认为回调模式与观察者模式的优缺点。
Callback pattern:
//example callback
public interface Callback{
public void notify(MethodResult result);
}
//example method
public class Worker{
public void doAsyncWork(Callback callback){
//do work
callback.notify(result);
}
}
//example observer pattern
public interface EventListener{
public void notify(MethodResult result);
}
public class Worker{
private EventListener listener;
public registerEventListener(EventListener listener){
this.listener=listener;
}
public void doAsyncWork(){
//do work
listener.notify(result);
}
}
我正在使用一个似乎使用这两种模式的框架。 EventListener 模式不是典型模式,因为它没有侦听器列表。这可以通过创建一个 CompositeListener 来轻松实现,该 CompositeListener 在侦听器的优先级以及如何处理向每个侦听器分配事件方面有自己的语义,例如为每个侦听器与串行通知生成一个新线程。 (我实际上认为这是一个好主意,因为它很好地分离了关注点,并且是对标准观察者/监听者模式的改进)。
关于什么时候应该使用它们有什么想法吗?
谢谢。
I'm trying to design an async framework and wanted to know what people think are the pros/cons of the callback pattern vs the observer pattern.
Callback pattern:
//example callback
public interface Callback{
public void notify(MethodResult result);
}
//example method
public class Worker{
public void doAsyncWork(Callback callback){
//do work
callback.notify(result);
}
}
//example observer pattern
public interface EventListener{
public void notify(MethodResult result);
}
public class Worker{
private EventListener listener;
public registerEventListener(EventListener listener){
this.listener=listener;
}
public void doAsyncWork(){
//do work
listener.notify(result);
}
}
I'm working with a framework which seems to use both of these patterns. The EventListener pattern is not the typical pattern as it doesn't have a list of listeners. This can easily be implemented though by creating a CompositeListener which has its own semantics on the priority of listeners and how to handle the distribution of events to each listener e.g. spawning a new thread for each listener vs serial notifications. (I actually think this is a good idea as its a good separation of concerns and is an improvement on the standard observer/listener pattern).
Any thoughts on when you should use each?
Thxs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
命令、回调和观察者模式具有不同的语义:
在您的示例中,您可以结合回调和观察者模式来实现更大的 API 灵活性:
Command, callback and observer patterns have different semantics:
In your example you could combine both callback and observer patterns to achieve greater API flexibility:
两种模式都很棒,选择哪一种取决于您要构建什么以及如何使用您的框架。
如果您正在尝试构建某种具有以下典型工作流程的发布-订阅系统:
,那么观察者模式是一个自然的选择为你。当您正在构建框架时,您还应该考虑使用 EventBus 模式来实现松散耦合。
如果您只需要一个简单的异步执行,并且使用框架的典型流程是:
或
,那么您应该使用简单的 <代码>回调。
但为了实现更可用和更干净的 API,我建议您摆脱
Callback
抽象,并设计您的工作代码以返回某种Future
。并且
Worker
可以按以下方式使用:Future
可以是标准的 java 未来。但我建议您使用 guava 库中的ListenableFuture
。Both patterns are great and which one to choose depends on what are you going to build and how your framework will be used.
If you are trying to build some kind of publish-subscribe system with following typical flow of work:
then
Observer
pattern is a natural choice for you. As you are doing a framework you should also consider using EventBus pattern to achieve loose coupling.If you need nothing more than a simple asynchronous execution and a typical flow using of your framework is:
or
then you should go with simple
Callback
.But in order to achieve more usable and clean API I'd recommend you to get rid of
Callback
abstraction and design your worker code to return a some kind ofFuture
.And
Worker
can be used following way:Future
could be a standard java Future. But I'd suggest you to useListenableFuture
from guava library.我认为回调模式更好,因为它更简单,这意味着它更可预测,并且由于其自身的变异状态而不太可能出现错误。操作中的一个示例是 GWT 处理浏览器/服务器通信的方式。
不过,您可能想使用泛型:
I'd argue that the callback pattern is better as it is simpler which means it'll be more predictable and less likely to have bugs due to it's own mutating state. An example of this in operation would be the way GWT handles browser / server communication.
You might want to use generics though:
让我们考虑一下 Lamp 和 Switch 的例子,看看观察者模式和命令模式之间的区别。
观察者模式
可以应用操作。
命令模式
另一方面,在命令模式中,动作 ON/OFF 变为命令
类。
命令类包含可以对其应用操作的接收器灯。
命令模式通常提供一对一的关系,但是也可以
也可以缩放以提供一对多。
命令模式为命令提供了适当的封装。
Lets consider the example of Lamp and Switch to see the difference between observer and command pattern.
Observer Pattern
actions can be applied.
Command Pattern
On the other hand in command pattern Actions ON/OFF becomes Command
class.
Command class contains receiver Lamp on which action can be applied.
Command pattern is often provides one to one relationship however can
be scaled to provide one to many as well.
Command pattern provides proper encapsulation to the command.
在您的具体代码中,Callback 和 EventListener 之间的唯一区别是:
前者更简单,后者更灵活。如果您正在创建一个可重用的框架,那么后者更有意义。
命令设计模式是在对象中执行操作所需的所有信息的封装,它与用于通知事件的机制无关。
In your specific code, the only differences between Callback and EventListener are:
The former is simpler, the latter is more flexible. If you are creating a reusable framework, the latter makes more sense.
The Command design pattern is the encapsulation of all information needed to perform an action in an object and it is has nothing to do with the mechanism used to notify events.
观察者模式和命令模式几乎没有共同的意图,并且可以组合。但不同之处在于他们的动机。
观察者模式描述了如何建立主体和观察者之间的关系。它并不专注于将命令创建为单独的类并对其进行参数化,以便可以存储命令对象并支持可撤消的操作。但这就是命令模式的作用。
命令模式描述了如何建立调用者、命令和接收者之间的关系。它并不关注如何支持任意数量的观察员以及如何管理他们。但这就是观察者模式的作用。
Both Observer and Command patterns share few common intentions and can be combined. But the difference is in their motivation.
Observer pattern describes how to establish the relationship between subject and observer. It didn't focus on creating a command as a separate class and parameterizing it so the command object can be stored and support undoable operations. But this is what the Command pattern does.
Command pattern describes how to establish the relationship between invoker, command, and receiver. It didn't focus on how to support any number of observers and how to manage them. But this is what the Observer pattern does.