多事件监听器的设计

时间:2021-12-07 00:02:29

I'm familiar with standard listeners, esp. in Java. For example, if you have a collection of objects, it might support a set of listeners for different things: CreateListener, ChangeListener, DeleteListener. Each has one method (e.g. objectChange) that is passed a list of affected objects. An app using this collection could register interest in one or more of these by implementing and register listener(s). When things happen to the objects in the collection, the appropriate listener gets invoked.

我熟悉标准听众,尤其是在Java中。例如,如果您有一组对象,它可能支持一组用于不同事物的侦听器:CreateListener,ChangeListener,DeleteListener。每个方法都有一个传递受影响对象列表的方法(例如objectChange)。使用此集合的应用程序可以通过实现和注册侦听器来注册其中一个或多个的兴趣。当集合中的对象发生事件时,将调用相应的侦听器。

But what if there are a number of these event types, perhaps similar but somewhat different. Would it make sense instead to define one listener class that has many methods. For example:

但是,如果有许多这些事件类型,可能相似但有些不同。是否有意义定义一个具有许多方法的侦听器类。例如:

class EventListener
{
    void objectsCreatedA( Object[] newObjects );
    void objectsCreatedB( Object[] newObjects );
    void objectsCreatedC( Object[] newObjects );

    void objectsChangedA( Object[] newObjects );
    void objectsChangedB( Object[] newObjects );
    void objectsChangedC( Object[] newObjects );

    void objectsDeletedA( Object[] newObjects );
    void objectsDeletedB( Object[] newObjects );
    void objectsDeletedC( Object[] newObjects );
}

This seems to make it easier for an app that wants to register for many of these events - they implement many methods in one class, rather than defining many classes that each implements only one method. Any drawbacks or other suggestions?

这似乎使想要注册许多这些事件的应用程序变得更容易 - 它们在一个类中实现了许多方法,而不是定义每个只实现一个方法的许多类。有任何缺点或其他建议吗?

Clarification edit: (sorry I got distracted with the holiday, not sure if this should be a separate post, but seems to make sense to follow-up on this one)

澄清编辑:(对不起,我对假期感到分心,不确定这应该是一个单独的帖子,但似乎有理由对此进行跟进)

I should have specified that this code will be implemented in multiple languages, as a framework that client apps will make use of. For C++, implementing multiple interfaces is difficult.

我应该指定这个代码将以多种语言实现,作为客户端应用程序将使用的框架。对于C ++,实现多个接口很困难。

A superset abstract listener could provide default do-nothing implementations for each method, so that a client extending it would only have to override the ones they care about. With this approach, we could later decide to add additional methods to the abstract class and existing clients would be ok (and can override those new methods if/when they choose to). And only one registration is needed with one invocation, rather than the alternative of many registration methods (with the app invoking one or many).

超集抽象侦听器可以为每个方法提供默认的do-nothing实现,因此扩展它的客户端只需要覆盖它们关心的那些。通过这种方法,我们以后可以决定向抽象类添加其他方法,并且现有客户端可以正常(并且可以在他们选择的时候覆盖这些新方法)。并且一次调用只需要一次注册,而不是许多注册方法的替代方案(应用程序调用一个或多个)。

With this clarification, does a superset abstract class make more sense than individual ones?

有了这个澄清,超集抽象类是否比单个抽象类更有意义?

3 个解决方案

#1


I would group that functions into an interface only if they are semantically similar (cohesion) and if it is very likely that an object interested in the event "objectsCreatedA" is also interested in "objectsCreatedB", otherwise you'll end with some classes with unimplemented functions: pretty ugly.

我会将这些函数分组到一个接口,只要它们在语义上相似(内聚),并且如果对“objectsCreatedA”事件感兴趣的对象很可能也对“objectsCreatedB”感兴趣,否则你将以一些类结束未实现的功能:非常难看。

As an alternative, if the events are really so similar, you could pass a "type" parameter, so the receiver can factorize out some code and choose what event type to process.

作为替代方案,如果事件非常相似,则可以传递“类型”参数,因此接收器可以分解出一些代码并选择要处理的事件类型。

#2


Since classes can implement multiple interfaces, I don't see that this saves you anything other than declaring that a single class implements a series of different listeners. It may, on the other hand, force classes to implement methods they don't actually need to implement.

由于类可以实现多个接口,因此除了声明单个类实现一系列不同的侦听器之外,我没有看到这可以节省您的任何其他内容。另一方面,它可以强制类来实现它们实际上不需要实现的方法。

#3


The only drawback I see to grouping all of those into one class is that the class could end up becoming fairly large and hard to read. That being said, if the listeners are not at all similar, you could end up with a massive class which a bunch of random functionality, which would have pretty high coupling.

我认为将所有这些组合成一个类的唯一缺点是该类最终可能变得相当大并且难以阅读。话虽如此,如果听众根本不相似,你最终可能会得到一个庞大的类,这个类具有一堆随机功能,这将具有相当高的耦合性。

If you do end up going this route, make sure that this listener only exists once (Singleton, static, whatever).

如果你最终走这条路线,请确保这个监听器只存在一次(Singleton,static,等等)。

#1


I would group that functions into an interface only if they are semantically similar (cohesion) and if it is very likely that an object interested in the event "objectsCreatedA" is also interested in "objectsCreatedB", otherwise you'll end with some classes with unimplemented functions: pretty ugly.

我会将这些函数分组到一个接口,只要它们在语义上相似(内聚),并且如果对“objectsCreatedA”事件感兴趣的对象很可能也对“objectsCreatedB”感兴趣,否则你将以一些类结束未实现的功能:非常难看。

As an alternative, if the events are really so similar, you could pass a "type" parameter, so the receiver can factorize out some code and choose what event type to process.

作为替代方案,如果事件非常相似,则可以传递“类型”参数,因此接收器可以分解出一些代码并选择要处理的事件类型。

#2


Since classes can implement multiple interfaces, I don't see that this saves you anything other than declaring that a single class implements a series of different listeners. It may, on the other hand, force classes to implement methods they don't actually need to implement.

由于类可以实现多个接口,因此除了声明单个类实现一系列不同的侦听器之外,我没有看到这可以节省您的任何其他内容。另一方面,它可以强制类来实现它们实际上不需要实现的方法。

#3


The only drawback I see to grouping all of those into one class is that the class could end up becoming fairly large and hard to read. That being said, if the listeners are not at all similar, you could end up with a massive class which a bunch of random functionality, which would have pretty high coupling.

我认为将所有这些组合成一个类的唯一缺点是该类最终可能变得相当大并且难以阅读。话虽如此,如果听众根本不相似,你最终可能会得到一个庞大的类,这个类具有一堆随机功能,这将具有相当高的耦合性。

If you do end up going this route, make sure that this listener only exists once (Singleton, static, whatever).

如果你最终走这条路线,请确保这个监听器只存在一次(Singleton,static,等等)。