设计模式学习——观察者模式

如果我们现在向一家报社订阅了一份报纸,那么这家报社不管今天我们有没有心情看报纸,它都会把报纸送过来。有一天我们实在是不想看这家的报纸了,我们如果取消了订阅,那么从此以后报社再也不会送报纸到我们家了。

上面这一段情景,其实和观察者模式的工作性质是一样的。


观察者模式

定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

其实就是有人发布信息,订阅的人都会收到通知,没订阅则不会收到通知。

  • 主题(Subject):主题类,发生改变时将给所有的观察者发布信息
  • 订阅者(Observer):订阅者,当主题改变时如果订阅了主题则会收到通知

例子

有粉丝关注了自己喜欢偶像的微博,一旦这个偶像微博动态发生了更新,那么粉丝就会接受到消息。

主题接口:

package observer;

/**
 * 主题接口
 * 有添加,删除,通知方法。
 */
public interface Observerable { ;
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyAllObersers();
}

观察者接口:

package observer;

/**
 * 观察者接口
 * 有更新方法
 */
public interface Observer {
    void update();
}

具体实现主题(明星):

package observer;

import java.util.ArrayList;

/**
 * 明星,一旦有风吹草动,粉丝立刻知晓。
 */
public class Star implements Observerable {
    private ArrayList<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyAllObersers() {
        for(Observer o : observers){
            o.update();
        }
    }
}

具体实现观察者(粉丝):

package observer;

/**
 * 粉丝,关注明星一举一动。
 */
public class Fans implements Observer {
    private Observerable star;

    private String name;

    public Fans(Observerable star,String name) {
        this.name = name;
        this.star = star;
        star.registerObserver(this);
    }

    @Override
    public void update() {
        System.out.println(this.name + " love my idol!!");
    }
}

测试

package test.observer;

import observer.Fans;
import observer.Observer;
import observer.Observerable;
import observer.Star;

public class test {
    public static void main(String args[]){
        Observerable star = new Star();
        Observer fans1 = new Fans(star,"Xiaohong");
        Observer fans2 = new Fans(star,"Xiaoming");
        Observer fans3 = new Fans(star,"Xiaolan");
        star.notifyAllObersers();


        star.removeObserver(fans3);
        star.removeObserver(fans2);
        star.notifyAllObersers();
    }
}

结语

在JDK中已经有了Observable与Observer,但是很遗憾,Observable是一个类,而不是一个接口,所以当类继承它时,扩展性将会变得极差,限制了它的使用和复用,但是Observable内有一个setChanged方法,可以来以此借助状态判断是否通知观察者,比较灵活,若自己实现主体接口的话,可以借鉴这种做法,有兴趣的同学可以自己查看JDK的源代码,在util包中。

在该设计模式中,体现了一个设计原则,即:

为交互对象之间的松耦合而努力

我们可以在观察者模式中明显的感受到,主题和观察者之间的松耦合。

主体只知道观察者实现了某个接口(即Observer),不需要知道观察者是谁,做了些什么或者其他细节,唯一依赖的是一个观察者的列表。假设有个新的类想当观察者,我们不需要更改主体的代码,只需新类实现接口,并注册到列表中去,这样的系统十分具有弹性,两者间的耦合降到了最低。


源码在这里:我的github地址


猜你喜欢

转载自blog.csdn.net/lpckr94/article/details/81158264