我使用了某种类型的“监听器”,在这种情况下,需要通知某些事件的类实现了一个接口(例如: CurrencyListener,有一个方法currencyUpdated(货币)),然后,需要发送通知的对象有一个侦听器列表(列表),并且只在调用currencyUpdated(货币)方法的列表上迭代。
这个监听器的结构非常类似于观察者模式,没有观察者和可观察的类,只有监听器接口(CurrencyListener)。
使用一种方法比另一种方法有什么好处/缺点?
发布于 2018-09-20 23:08:51
这是观察者的模式-这是完全一样的东西。
我使用了某种类型的“侦听器”,在这种情况下,需要通知某些事件的类实现了一个接口(例如: CurrencyListener,带有currencyUpdated(货币)方法)。
在观察者模式中,您有一个抽象(接口或基类)观察者,它定义了观察者可以观察(或侦听)的东西。您的CurrencyListener是观察者。
模式的另一部分是可观察的,它是发送通知的对象,它本身可能是抽象的,也可能不是某种层次结构的一部分。即,该模式不要求存在ConcreteObservable子类。在Go4模式书中,ConcreteObservable的一个角色被描述为
“存储ConcreteObserver对象感兴趣的状态。”
如果ConcreteObserver不需要任何特殊的状态,或者只可以使用可观察的基类提供的接口,那么就不需要ConcreteObservable。
然后,需要发送通知的对象有一个侦听器(列表)列表,并且只在调用currencyUpdated(货币)方法的列表上迭代。
观察者为可观察的/侦听器提供了向其注册的方法,并在内部维护这些侦听器的集合。你的目标就是这么做的。
再说一次,这只是经典的观察者模式。观察者和可观察对象是相互独立的,因为它们都依赖于观察者接口提供的抽象,也因为它们依赖于客户端代码来将观察者/侦听器与可观察的对象连接起来。
在这个模式上有许多不同的变化,不同语言中的许多特性都是伪装的观察者模式。例如,在C#中,事件显然是模式的变化。另一个变体的例子是通常被称为Messenger (或者像Martin Fowler所说的事件聚合器),它可以在一些库和框架中找到--它是一个类,充当观察者和观测者之间的中介。结构略有不同,但它基于观察者模式;实际上,Go4书在描述模式的实现部分的末尾描述了类似的东西(他们称之为ChangeManager)。
发布于 2018-09-20 22:16:38
你的听众非常接近观察者。然而,它们似乎与一个非常具体的观察主题(如Currency)紧密相连。因此,侦听其他类型的主题将需要额外的侦听器接口和类似的调度方法的额外实现。
相反,原始的观察者模式通过在观察的主题(以下称为可观察的)和观察者之间提供抽象的耦合来确保可重用和可扩展。这允许模式的每一方进一步独立地进行专门化。
总之,你的听众并不是完全的观察者。
我理解以下设计:
CurrencyListener实现CurrencyListener.currencyUpdated(Currency currency)接口。CurrencyListener的列表,currencyUpdated()方法。未决问题:
映射您的设计
将您的设计与观测器设计模式进行比较表明:
Observable (除非Currency是)Observer的集合。CurrencyListener是一个Observer接口CurrencyUpdated()方法是update()方法。ObserverCurrencyListener强加了update函数将接收的对象的具体类型。这种类型似乎非常具体,并与通知发送方密切联系。因此,为一种新的可观测对象实现侦听器每次都需要一个新的接口。Observer.update()不需要知道具体的Observable。这允许将实现解耦。混凝土Observer知道混凝土Observable,并能得到它的状态。一个已知的变体是Observer.update(Observable o)。因此,观察者仍然与可观察到的具体实现(也)脱钩。你的听众都很好。如果你只有一种可观察的科目,他们甚至可以简化设计。
但是,使用观测器模式对它们进行重构可能有助于将部件解耦,这将有助于重用和提高灵活性。
发布于 2019-07-28 01:26:23
它们是一样的,观察者模式是一种模式,侦听器是基于该模式的实现。
其他答案只是指出了命名方法的方式并不能使您的观察者系统可重用。因此,只需尝试使用"update“而不是"updateCurrency”来命名该方法。
https://softwareengineering.stackexchange.com/questions/378748
复制相似问题