在委托模式中,只有一个对象可以直接侦听另一对象的事件。在观察者模式中,任意数量的对象都可以侦听特定对象的事件。当设计一个需要通知其他对象事件的类时,为什么要在观察者模式上使用委托模式?我认为观察者模式更加灵活。您现在可能只有一个观察者,但是将来的设计可能需要多个观察者。
在委托模式中,只有一个对象可以直接侦听另一对象的事件。在观察者模式中,任意数量的对象都可以侦听特定对象的事件。当设计一个需要通知其他对象事件的类时,为什么要在观察者模式上使用委托模式?我认为观察者模式更加灵活。您现在可能只有一个观察者,但是将来的设计可能需要多个观察者。
Answers:
您看错了东西。观察者看到发生了特定事件。它不会影响它,也不会拥有它。委托人处理特定事件,并拥有处理程序的所有权,即使委托人拥有事件的接口也是如此。
这是几个权衡的问题。
权衡:
委托模式:
观察者模式:
据我了解,委托模式在其他语言(例如Delphi)中称为事件处理程序机制。这样,它只是观察者模式的一个实现,但有一个主要限制:一次只能一个监听者。
事件处理程序或委托的缺点很明显:只有一个观察者。
优势不是那么明显:性能。使用观察者模式,您可以添加许多观察者。当发生需要通知观察者的事件时,您将需要枚举观察者并将通知发送给每个观察者。这会很快使任何观察到的实例陷入困境,特别是当需要通知的事件数量也很大时。
int (*my_int_f)(int)
在C中)。我一直认为,通过使它更像struct / enum来使它们更容易理解。事件是使用单个委托签名的灵活侦听器数组的挂钩。您可以在没有事件的情况下做到这一点(这就是为什么我认为OP表示委派模式的原因,这是非常不同的),但是这种语言使您变得更轻松。
这是一篇过时的文章,但无论如何我都会很高兴,因为其他答案都没有涉及使用任何一种模式时发生的情况,它们似乎更多是关于理论而非实践。
委派和观察员如何工作
通过委派,委托人可以精确地选择在潜在事件源创建后谁将对特定事件做出响应。您可以将这个侦听器视为一个观察者。在观察者模式的情况下,观察者会在感觉到的时候选择观察者。因此,在观察者与委派之间的依赖关系是相反的。使用观察者模式,可以将报纸和订阅者视为观察者。观察者可以控制何时创建关系。与代表团一起思考一个雇员和一个雇主。雇主控制何时建立关系以及确切地由谁负责特定事件。员工通常无法选择他们正在执行的任务。
有人认为代表团可以有一名观察员,但我认为两者之间的真正区别在于事件处理的分配方式。您将永远不会看到代表注册事件。直到事件发生并且委托者对此事件调用一个公共方法之前,它永远都不会知道它的事件处理方式。
委托优势
这种图案非常刚性,在大多数常规设计中,它更简单且通常更坚固。它迫使您在初始化潜在事件的源时预先声明事件处理程序。如果您需要某人指挥交通,您可以在开阔街道之前指定一名交通总监。就观察员而言,您可以让交通警察随时选择何时引导交通。
委派劣势
这种设计的缺点是它不灵活。如果您正在实施一些用于订阅报纸的代码,则报纸/代理人将必须准确地确定谁可以在创建新闻后的第二个月阅读新闻故事。通过观察者模式,他们可以在以后的任何时间进行注册,而报纸只需要知道有新人签约即可。
何时选择委派?
当您确定需要一个特定的观察者并且没有理由要更改观察者时,僵化的委派模式设计将是有益的。
例如,您需要一个类/对象来处理针对特定错误的弹出窗口。没有太多原因为什么需要在运行时切换谁正在处理特定错误,因此将“内存不足”错误委托给单个实体是有意义的。创建一个潜在的处理程序数组,然后让这些处理程序注册“内存不足”错误没有多大意义;这将是在这种情况下使用观察者模式的示例。在运行时,您可能想更改变量事件的调用方法或调用“委托”的方法,但是在运行时将事件处理程序换为特定事件是不正常的。
像您在观察者模式中那样交换代表不是没有可能,这只是很复杂。在现实世界中,您可能想交换交通警察,以便由新的委托人来处理交通。有人可能会争辩说,一种更好的设计会使原委派成为一个警察局,而不是一个警察,但我离题了。