多事件监听器的设计

发布于 2024-07-25 09:48:07 字数 1198 浏览 4 评论 0原文

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

但是,如果有许多此类事件类型,可能相似但又有所不同,该怎么办? 定义一个具有多种方法的侦听器类是否有意义? 例如:

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 );
}

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

澄清编辑:(抱歉,我因假期而分心,不确定这是否应该是一个单独的帖子,但似乎对这个帖子进行后续处理是有意义的)

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

超集抽象侦听器可以为每个方法提供默认的不执行任何操作的实现,以便扩展它的客户端只需重写他们关心的方法。 通过这种方法,我们稍后可以决定向抽象类添加其他方法,现有客户端就可以了(并且如果/当他们选择时可以覆盖这些新方法)。 并且一次调用只需要一次注册,而不是多种注册方法的替代方案(应用程序调用一种或多种)。

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

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.

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.

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).

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一曲琵琶半遮面シ 2024-08-01 09:48:07

仅当这些函数在语义上相似(内聚)并且对事件“objectsCreatedA”感兴趣的对象很可能也对“objectsCreatedB”感兴趣时,我才会将这些函数分组到一个接口中,否则您将以一些类结束未实现的功能:非常丑陋。

作为替代方案,如果事件确实如此相似,您可以传递“类型”参数,以便接收者可以分解一些代码并选择要处理的事件类型。

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.

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.

裂开嘴轻声笑有多痛 2024-08-01 09:48:07

由于类可以实现多个接口,因此除了声明单个类实现一系列不同的侦听器之外,我认为这不会为您节省任何东西。 另一方面,它可能会强制类实现它们实际上不需要实现的方法。

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.

放赐 2024-08-01 09:48:07

我认为将所有这些分组到一个类中的唯一缺点是该类最终可能会变得相当大并且难以阅读。 话虽这么说,如果侦听器完全不相似,您最终可能会得到一个庞大的类,其中包含一堆随机功能,这将具有相当高的耦合性。

如果您最终选择了这条路线,请确保该侦听器仅存在一次(单例、静态等)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文