Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 具有事件而非参数的观察者模式(推送模型)_Design Patterns_Observer Pattern - Fatal编程技术网

Design patterns 具有事件而非参数的观察者模式(推送模型)

Design patterns 具有事件而非参数的观察者模式(推送模型),design-patterns,observer-pattern,Design Patterns,Observer Pattern,现在我正试图完全理解观察者模式的概念 据我所知(如果我错了,请纠正我): 如果不同的观察者需要不同的参数集,并且您不希望UpdateFunction包含所有变量,建议使用事件而不是参数 =>updateFunction中不必要的数据传输 =>updateFunction需要一个以上参数时出现的问题(您必须更改所有观察者) 你能给我解释一下使用事件如何解决这个问题,以及如何实现这个问题吗?(可能在Java中?假设我们有一个使用接受参数列表的方法定义的观察者接口,如下所示 接口观察者{ void d

现在我正试图完全理解观察者模式的概念

据我所知(如果我错了,请纠正我): 如果不同的观察者需要不同的参数集,并且您不希望UpdateFunction包含所有变量,建议使用事件而不是参数

=>updateFunction中不必要的数据传输

=>updateFunction需要一个以上参数时出现的问题(您必须更改所有观察者)


你能给我解释一下使用事件如何解决这个问题,以及如何实现这个问题吗?(可能在Java中?

假设我们有一个使用接受参数列表的方法定义的观察者接口,如下所示

接口观察者{
void doObserve(字符串名称、字符串值);
}
然后,假设我们有几个类实现该接口

类Observer实现了Observer{ @凌驾 public void doObserve(字符串名称、字符串值){ } } 类Observer实现Observer{ @凌驾 public void doObserve(字符串名称、字符串值){ } } 现在假设随着时间的推移,需求发生了变化,一些观察者需要了解一些附加信息,例如“描述”。为了实现这个需求,我们必须回去更改
Observer
中定义的方法签名,并更新实现接口的所有类

接口观察者{
void doObserve(字符串名称、字符串值、字符串描述);
}
类Observer实现了Observer{
@凌驾
public void doObserve(字符串名称、字符串值、字符串描述){
}
}
类Observer实现Observer{
@凌驾
public void doObserve(字符串名称、字符串值、字符串描述){
}
}
如果我们将这些参数分组为一个“事件”对象或“参数”对象,那么我们将
Observer
接口与类中的具体实现分离

类observer事件{
字符串名;
字符串值;
//为简洁起见省略了getter/setter
}
界面观察者{
void doObserve(观察者事件);
}
类Observer实现了Observer{
@凌驾
public void doObserve(观察者事件){
}
}
类Observer实现Observer{
@凌驾
public void doObserve(观察者事件){
}
}
重放前面的场景,如果我们对描述字段有新的需求,那么我们可以简单地将其添加到
ObserverEvent
中,并且可以选择只修改关心使用描述的特定类

类observer事件{
字符串名;
字符串值;
字符串描述;
}
这是一个小得多的代码更改


在本例中,两个代码更改都不是很困难。在一个非常大的代码库中,尽管有许多
Observer
的实现,但像这样将参数与接口的方法签名分离确实可以简化维护。常规代码更改不需要编辑这么多文件。方法签名不会爆炸成一个包含太多参数的列表,这样就很难阅读。

我使用两种方法,可以组合使用:

1) 使用特殊的上下文对象在观察者和可观察对象之间共享数据。您可以将数据放入上下文对象,将其传递给观察者,并让他们更改其中的数据。被观察者通知的可观察对象读取上下文并使用该数据。例如,您可以使用观察者模式来完成某些工作。作业完成后,通知每个可观察对象。Observable读取在构造函数级别注入观察者的共享上下文,并确定现在哪些资源可用于启动另一个作业


2) 使用将作为Notify()方法参数的通知或事件类。此事件对象具有可观察对象读取的EventParams属性。例如,当您的观察者引发进度事件(ProgressEvent e)时,您可以读取其e.EventArgs.Status并根据需要使用。您可以为ObserverEvent和ObserverEventParams创建接口,并为每种类型的事件实现该接口。在您的observable类中,您仍然可以接受接口,然后使用责任链模式或类似的模式

感谢您的快速回复。但这并不能解决不必要的数据传输问题。假设ObserverA只需要一个参数doObserve(字符串名),如果我们传递ObserverEvent,ObserverA将获得所有值。。。如果我们有很多观察者,并且只有其中一些人需要处理这个特定事件,那么这可能会有问题。我认为观察者模式或使用事件类封装其参数没有任何固有的东西专门解决这个问题。如果您真的想保证某些观察者接收一组参数(并且仅接收这些参数),而其他观察者接收另一组参数(并且仅接收这些参数),那么这可能表明需要使用两种不同的方法签名的两种不同类型的观察者接口。@Ayox,我很高兴听到这有帮助。如果您愿意,您可以将此标记为已接受的答案,而无需等待声誉。作为奖励,当你接受答案时,你会得到+2。我认为这足以让你获得15%的声誉,这让你有权开始投票问答。欢迎来到堆栈溢出社区!:-)非常感谢您的回答:)可以分享一个例子吗?我真的不知道我是否正确地理解了它;)如果你不能理解一个想法,我的例子就帮不了你;)在使用之前,先自学基本模式。使用模式而不理解它们是一件坏事