观察者模式

观察者模式只是一种编程思想
观察者模式:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。而观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被改变的时候,会触发观察者的事件。在这里插入图片描述
在这里插入图片描述
发布订阅模式:在“发布者-订阅者”模式中,称为发布者的消息发送者不会将消息编程为直接发送给称为订阅者的特定接收者。这意味着发布者和订阅者不知道彼此的存在。存在第三个组件,称为代理或消息代理或事件总线,它由发布者和订阅者都知道,它过滤所有传入的消息并相应地分发它们。换句话说,pub-sub是用于在不同系统组件之间传递消息的模式,而这些组件不知道关于彼此身份的任何信息。经纪人如何过滤所有消息?实际上,有几个消息过滤过程。最常用的方法有:基于主题和基于内容的。
在这里插入图片描述
java中的观察者模式:
java API提供一个主题Subject,但是这个主题是一个类只能继承,如果项目需要继承其它东西,则可以自己定义一个主题接口。查看提供的源码,具体的主题把观察者都集中保存在了Vector容器中,它的通信模式即在notifyObservers方法中,当主题变化,此方法通知所有的观察者。

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;
    
public void notifyObservers(Object arg) {
        Object[] arrLocal;
        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }
        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

...
}

观察者Observer 接口,通过观察主题的实现,当执行notifyObservers方法时,观察者的update方法会执行,即成功实现了对象的一对多的通知。

public interface Observer {
    /**
     * This method is called whenever the observed object is changed. 
     */
    void update(Observable o, Object arg);
}

下面是具体的例子:
具体主题:

package observerTest;

import java.util.Observable;

/**
 * 报纸对象,具体的目标实现
 */
public class NewsPaper extends Observable {
    /**
     * 报纸的具体内容
     */
    private String content;
    /**
     * 获取报纸的具体内容
     * @return 报纸的具体内容
     */
    public String getContent() {
        return content;
    }
    /**
     * 示意,设置报纸的具体内容,相当于要出版报纸了
     * @param content 报纸的具体内容
     */
    public void setContent(String content) {
        this.content = content;
        //内容有了,说明又出报纸了,那就通知所有的读者
        //注意在用Java中的Observer模式的时候,这句话不可少
        this.setChanged();
        //然后主动通知,这里用的是推的方式
        //this.notifyObservers(this.content);
        //如果用拉的方式,这么调用
        this.notifyObservers();
    }
}

具体观察者

package observerTest;

import java.util.Observable;
import java.util.Observer;

/**
 * 真正的读者,为了简单就描述一下姓名
 */
public class Reader implements Observer {
    /**
     * 读者的姓名
     */
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void update(Observable o, Object obj) {
        //这是采用推的方式
        //System.out.println(name+"收到报纸了,阅读先。目标推过来的内容是==="+obj);
        //这是获取拉的数据
        System.out.println(name+"收到报纸了,阅读先。主动到目标对象去拉的内容是==="
        +((NewsPaper)o).getContent());
    }
    
}

客户端

package observerTest;

public class Client {
    public static void main(String[] args) {
        //创建一个报纸,作为被观察者
        NewsPaper subject = new NewsPaper();
        
        //创建阅读者,也就是观察者
        Reader reader1 = new Reader();
        reader1.setName("张三");
        
        Reader reader2 = new Reader();
        reader2.setName("李四");
        
        Reader reader3 = new Reader();
        reader3.setName("王五");
        
        //注册阅读者
        subject.addObserver(reader1);
        subject.addObserver(reader2);
        subject.addObserver(reader3);
        
        //要出报纸啦
        subject.setContent("观察者模式测试+++++++++++++++++++++++++++++++");
    }
}

参考附录:
https://blog.csdn.net/weixin_38003389/article/details/88052943

posted @ 2020-03-04 15:04  小小白兔兔  阅读(158)  评论(0编辑  收藏  举报