观察者模式:定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,他的所有者都会受到通知并自动更新。
观察者模式的方法不止一种,但是以包含Subject和Observer接口的类设计的做法最常见。
观察者模式和一对多的关系有何联系:
利用观察者模式,主题是具有状态的对象,并且可以控制这些状态。也就是说,有"一个"具有状态的主题。另一方面,观察者使用这些状态,虽然状态不属于他们。有许多观察者,依赖主题告诉他们状态何时改变了。这就产生了一个关系:"一个"主题对"多个"观察者的关系。
期间的依赖是如何产生的:
因为主题是真正拥有数据的人,观察者模式是主体的依赖者,在数据变化时更新,这样比起让许多对象控制同一份数据来,可以得到更加干净的OO设计。
观察者模式提供了让主体和观察者之间松耦合的对象设计方式。
主题唯一依赖的东西就是实现Obeserver接口的对象列表,主题只知道观察者实现了这个接口,而不需要知道它具体是谁、做什么。我们也可以随时增加(删除)观察者。也不需要为新类型的观察者修改主题代码,它只需实现接口即可。
两种方式。
1.主题"推"数据,把所有数据一次性发送给所有注册的观察者。
缺点:不是每个观察者都需要所有数据;主题扩展新的属性,需要修改对观察者的调用。
2.观察者主动去拉数据。
缺点:可能需要调用多次的getter、setter方法。
用两个例子,第一个例子是自建的观察者模式:
输出:
Java为观察者模式提供了内置的支持。
运作模式:
主题:java.util.Observable;
观察者:java.util.Observer;
addObserver(Observer o),deleteObserver(Observer o);
主题送出通知:
1.先调用setChanged()方法,标记状态已经改变的事实。
setChanged()方法用来标记状态已经改变的事实,好让notifyObserver()知道当它被调用时应该更新观察者。
java内部实现类似于
好处:可以在通知观察者时有更大的弹性。hasChanged()告诉你现在changed的状态
2.两种notifyObservers()
notifyObservers()或
notifyObservers(Object arg);此版本可以传送任何的数据。
观察者接受通知:
update(Observable o,Object arg)参数一,哪个主题;参数二,传入数据。
输出:
Java内置Observer的缺点:
!!不要依赖于观察者被通知的次序。
1.在这里,我们可以看到,Obserable是一个类而非接口。他违反了设计原则:针对接口而非实现编程。Java不支持多继承,这种设计限制了Observable的复用能力。
2.Observable将关键的方法保护起来:serChanged()方法是protected的。除非亲自继承Observable,否则无法使用。这意味者无法通过组合的方式,违反了设计原则:多用组合,少用继承。
因此,如果需要扩展功能,建议像开始一样自己写个观察者模式。