JAVA ·

程序设计模式之观察者模式

所谓的观察者模式应该就是发布/订阅的模式。举个例子:当你在某某直播平台看到一个漂亮的小姐姐唱歌唱的很好,你想一旦小姐姐直播的时候你就能第一时间知道,以便你可以流着哈喇子看小姐姐唱歌,跳舞,那么你就需要订阅这个直播的小姐姐了。

上面只是一个比较通俗的比喻,在上面这个比喻中你就是观察者,小姐姐就是被观察者。在软件中A对象想知道B对象是否发生了某些变化,以便自己能及时收到变化的内容并且自身做出相应的改变。那么A就是观察者,B就是被观察者,在java的jdk中就内置了这种实现:ObeservableObserver,其中Obeservable是一个类,Observer是一个接口。

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;
    public Observable() 
    public synchronized void addObserver(Observer o)
    public synchronized void deleteObserver(Observer o)
    public void notifyObservers() 
    public void notifyObservers(Object arg) 
    public synchronized void deleteObservers() 
    protected synchronized void setChanged()
    protected synchronized void clearChanged() 
    public synchronized boolean hasChanged()
    public synchronized int countObservers() 
}
public interface Observer {
    void update(Observable o, Object arg);
}

在代码中被观察者(主题)需要继承Observable并且选择重写其中的方法,观察者实现Observer接口,当主题发送变化的时候就会调用notifyObservers函数来通知观察者。其中很多函数都被synchronized关键字修饰说明Observable是线程安全的。总的来说使用jdk内置的观察者模型是很不错的,但是却还是不完美。

  1. Obseravble是一个类不是一个接口,所以必须使用继承。如果想具有其他超类的属性或者是行为是无法做到的(java不支持多继承)。这样导致代码的复用率比较低,违反了我们之前的规则:少用继承,多用组合。
  2. setChange函数是被protected修饰的,这就导致你必须继续Observable,因此扩展性差。

那么在某些情况下,我们就需要自己来实现观察者模式,而不是依赖jdk中内置的API。根据之前的设计规则。我们把Obervable做出一个借口就好。

public interface Suject{
    public  void addObserver(Observer o)
    public  void deleteObserver(Observer o)
    public void notifyObservers() 
}

当然上面只是一个简单的实现,你可以根据自己的需求添加,并且有必要也可以自定义Observer。注意线程安全的问题。在有些需求中有些对象既可能是观察者也有可能是被观察者。

观察者模式在很多软件中都有很好的应用,因为它不仅可以及时得到通知,并且还可以降低模块之间的耦合。IBM的mqtt服务就是一个观察者模型,当用户A在mqtt服务中订阅了某个主题,就会收到Mqtt关于这个主题的推送。

在这之前,虽然我对观察者模式有所了解,并且在应用中也使用过Jdk内置的API实现过,但我个人感觉我还是不能徒手写出来,必须借助资料,更别说知道使用内置的观察者api还会有如此缺陷。借助这次看书和总结进一步加深了对设计模式的思考和应用。虽然需要花费一些时间,但是相对比单独看书效果还是好很多。大部分人看书只是被动接收,没有去带着问题去看,没有去思考,更别说写总结。这样就会像我这样过一段时间就会忘记看过的内容。

书上得来终觉浅,绝知此事要躬行!!!!

参与评论