Java 观察者模式:独立观察属性

Java 观察者模式:独立观察属性,java,design-patterns,observer-pattern,Java,Design Patterns,Observer Pattern,我想问一下,当我需要实现以下目标时,我应该如何正确地实现观察者模式: WeatherStation[temperature, humidity ...] 我需要能够独立地“观察”每个属性。因此,当温度变化时,只通知温度观察员,当湿度变化时,只通知湿度订户 我的想法是,我将创建一些类,如ObservateTemperature和interface TemperatureObserver,但通过这种方式,我必须为每个属性创建两个“类” 第二种选择是为每个属性(如TemperatureSource、

我想问一下,当我需要实现以下目标时,我应该如何正确地实现观察者模式:

WeatherStation[temperature, humidity ...]
我需要能够独立地“观察”每个属性。因此,当温度变化时,只通知温度观察员,当湿度变化时,只通知湿度订户

我的想法是,我将创建一些类,如ObservateTemperature和interface TemperatureObserver,但通过这种方式,我必须为每个属性创建两个“类”

第二种选择是为每个属性(如TemperatureSource、TemperatureObserver…)只创建两个接口,然后在WeatherStation类中实现xxxSource接口,但这样它就不可重用,我需要在WeatherStation类中有很多数组(与“可观察”属性的数目相同)跟踪观察者

还有更好的选择吗

编辑:
还有一种情况,我可能会有一个类似Display的类,它订阅多个属性(不是全部),并且仍然需要区分其中哪一个被更新。

温度
湿度
等组合到一个类中
气象站
定义了一个域概念。就观察者模式而言,这是一个主题。另一方面,发送由单个值组成的通知将
气象站
划分为多个领域概念和多个主题。显然,这两个设计决策之间存在冲突

GoF模式是根据对象(而不是字段)作为主题来定义的。但请注意,这并不限制受试者在不同时间通知不同的观察者。这本书的相关章节从第298页开始

明确指定感兴趣的修改。您可以通过扩展主题的注册界面来提高更新效率,从而允许仅为感兴趣的特定事件注册观察员。当此类事件发生时,受试者仅通知对该事件感兴趣的观察者。支持这一点的一种方法是对主题对象使用方面的概念。为了记录对特定事件的兴趣,观察者使用

void Subject::Attach(Observer*, Aspects interest);
其中,
interest
指定感兴趣的事件。在通知时,主体将更改的方面作为更新操作的参数提供给其观察者。例如:

void Observer::Update(Subject*, Aspect& interest);

这种方法使不同的观察者能够从一个
主题注册不同的通知。请注意,无论观察者注册哪个方面,它都会在通知消息中接收相同的
主题。由观察者从
主题

中读取必要字段,将
温度
湿度
等组合到一个类中
气象站
定义了一个域概念。就观察者模式而言,这是一个主题。另一方面,发送由单个值组成的通知将
气象站
划分为多个领域概念和多个主题。显然,这两个设计决策之间存在冲突

GoF模式是根据对象(而不是字段)作为主题来定义的。但请注意,这并不限制受试者在不同时间通知不同的观察者。这本书的相关章节从第298页开始

明确指定感兴趣的修改。您可以通过扩展主题的注册界面来提高更新效率,从而允许仅为感兴趣的特定事件注册观察员。当此类事件发生时,受试者仅通知对该事件感兴趣的观察者。支持这一点的一种方法是对主题对象使用方面的概念。为了记录对特定事件的兴趣,观察者使用

void Subject::Attach(Observer*, Aspects interest);
其中,
interest
指定感兴趣的事件。在通知时,主体将更改的方面作为更新操作的参数提供给其观察者。例如:

void Observer::Update(Subject*, Aspect& interest);

这种方法使不同的观察者能够从一个
主题注册不同的通知。请注意,无论观察者注册哪个方面,它都会在通知消息中接收相同的
主题。由观察者从
主题
中读取必要的字段

好吧,你可以使用标准/通用类,只需注册观察者的单个属性,或者如果你想让它更安全,可以使用泛型,例如,
ObservableProperty
PropertyObserver
。这样我就需要为每种类型创建类,对吗?因为例如,如果两个属性是同一类型(Float),我将无法区分它们。另外,我认为Java中不存在PropertyObserver,至少我找不到它。是的,如果你需要属性是类型安全的,那么每种类型都需要一个类。不过,在大多数情况下,您不需要这样做,只需为不同的属性注册同一观察器接口的实例(例如,类似以下伪代码
getObservable(“temperature”).register(new observator(){…})
。是的
PropertyObserver
可能不存在,但是如果你不能使用任何现有的类和接口,你也可以使用自己的。这听起来很有趣,如果没有更好的解决方案建议,我可能会这样做。但我仍然认为我必须为属性创建这些类即使我不需要它是类型安全的,因为如果我是对的,我不能说什么时候观测者是由温度触发的,什么时候是由湿度触发的。你通常会在每个属性上注册不同的观测者,所以如果你在“湿度”y上触发观测者