千家信息网

JAVA的观察者模式的作用是什么

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,今天就跟大家聊聊有关JAVA的观察者模式的作用是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。当对象间存在一对多关系时,则使用观察者模式(
千家信息网最后更新 2026年10月31日JAVA的观察者模式的作用是什么

今天就跟大家聊聊有关JAVA的观察者模式的作用是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。观察者模式是Java非常重要的一个设计模式。

观察者模式所涉及的角色有:

  ●  抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

  ●  具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。

  ●  抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

  ●  具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

抽象主题(subject)角色:

import java.util.ArrayList;import java.util.List;public abstract class Subject {    private Listlist = new ArrayList<>();    public void register(MyObserver myObserver){        if (!list.contains(myObserver)){            list.add(myObserver);        }    }    public void remove(MyObserver myObserver){        if (list.contains(myObserver)){            list.remove(myObserver);        }    }    public void notifyObserver(){        for (MyObserver myObserver : list) {            myObserver.update();        }    }}

抽象观察者角色:

public interface MyObserver {    void update();}

具体主题角色:

public class Repoter extends Subject {    private String msg;    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;        if (change()) {            notifyObserver();        }    }    public Boolean change() {        if (msg.equals(getMsg())) {            return true;        } else {            return false;        }    }}

第一个具体观察者对象:

public class PeopleDaily implements MyObserver {    private Subject subject;    public PeopleDaily(Subject subject) {        this.subject = subject;        subject.register(this);    }    @Override    public void update() {        System.out.println("人民日报发布最新报道:" + ((Repoter) subject).getMsg());    }    public void remove() {        subject.remove(this);    }}

第二个具体观察者对象:

public class NewsFeeds implements MyObserver {    private Subject subject;    public NewsFeeds(Subject subject) {        this.subject = subject;        subject.register(this);    }    @Override    public void update() {        System.out.println("新闻联播发布最新报道:" + ((Repoter) subject).getMsg());    }    public void remove() {        subject.remove(this);    }}

第三个具体观察者对象:

public class XinHuaNewsAgency implements MyObserver {    private Subject subject;    public XinHuaNewsAgency(Subject subject) {        this.subject = subject;        subject.register(this);    }    @Override    public void update() {        System.out.println("新华社发布最新报道:" + ((Repoter) subject).getMsg());    }    public void remove() {        subject.remove(this);    }}

测试:

public class TestDemo {    @Test    public void demo(){        Repoter repoter = new Repoter();        NewsFeeds newsFeeds = new NewsFeeds(repoter);        XinHuaNewsAgency xinHuaNewsAgency = new XinHuaNewsAgency(repoter);        PeopleDaily peopleDaily = new PeopleDaily(repoter);        repoter.setMsg("为实现中华民族伟大复兴而奋斗!!!");    }}

结果:

新闻联播发布最新报道:为实现中华民族伟大复兴而奋斗!!!新华社发布最新报道:为实现中华民族伟大复兴而奋斗!!!人民日报发布最新报道:为实现中华民族伟大复兴而奋斗!!!Process finished with exit code 0

删除一个观察者再试:

public class TestDemo {    @Test    public void demo(){        Repoter repoter = new Repoter();        NewsFeeds newsFeeds = new NewsFeeds(repoter);        XinHuaNewsAgency xinHuaNewsAgency = new XinHuaNewsAgency(repoter);        PeopleDaily peopleDaily = new PeopleDaily(repoter);        repoter.setMsg("为实现中华民族伟大复兴而奋斗!!!");        repoter.remove(xinHuaNewsAgency);        System.out.println("------------------------------------------------");        repoter.setMsg("华为发布最新旗舰机Mate30系列型号手机");    }}

结果:

新闻联播发布最新报道:为实现中华民族伟大复兴而奋斗!!!新华社发布最新报道:为实现中华民族伟大复兴而奋斗!!!人民日报发布最新报道:为实现中华民族伟大复兴而奋斗!!!------------------------------------------------新闻联播发布最新报道:华为发布最新旗舰机Mate30系列型号手机人民日报发布最新报道:华为发布最新旗舰机Mate30系列型号手机Process finished with exit code 0

对于观察者模式,JDK已经为我们提供了对应的接口和类。

JDK源代码:

package java.util;/** *  * 当一个类想要被告知可观察对象的变化时,它可以实现 Observer 接口。 * @author  Chris Warth * @see     java.util.Observable * @since   JDK1.0 */public interface Observer {    /**     *      * 每当观察对象发生变化时,都会调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,以便让所有对      * 象的观察者收到更改通知。     * @param   o     the observable object.     * @param   arg   an argument passed to the notifyObservers     *                 method.     */    void update(Observable o, Object arg);}

Observer是一个接口,只是一个方法update用于接收通知者的通知并做出相应,具体的逻辑肯定是需要开发者自己实现的了。

被观察者,JDK的源码如下:

package java.util;/** *  * 此类表示可观察对象,或模型 - 视图范例中的"数据"。它可以被子类化以表示应用程序想要观察的对象。  * 可观察对象可以有一个或多个观察者。观察者可以是实现接口 Observer 的任何对象。 * 在可观察的实例发生更改后,调用 Observable 的 notifyObservers 方法,应用程序会通过调用 update 来通知所有观察  * 者的更改。  * 未指定通知的递送顺序。 Observable类中提供的默认实现将按照它们注册的顺序通知Observers,但是子类可能会更改此顺  * 序,使用不保证顺序,在单独的线程上发送通知,或者可以保证它们的子类遵循此顺序,因为它们选择。  * 请注意,此通知机制与线程无关,并且与类 Object 的 wait 和 notify 机制完全分开。  * 当新创建可观察对象时,其观察者集合为空。当且仅当 equals 方法为它们返回true时,才认为两个观察者是相同的。 * @author  Chris Warth * @see     java.util.Observable#notifyObservers() * @see     java.util.Observable#notifyObservers(java.lang.Object) * @see     java.util.Observer * @see     java.util.Observer#update(java.util.Observable, java.lang.Object) * @since   JDK1.0 */public class Observable {    private boolean changed = false;    private Vector obs;    //构造方法    public Observable() {        obs = new Vector<>();    }    /**     * 将观察者添加到此对象的观察者集中,前提是它与集合中已有的某个观察者不同。未指定将通知发送给多个观察者的顺序。     * @param   o   an observer to be added.     * @throws NullPointerException   if the parameter o is null.     */    public synchronized void addObserver(Observer o) {        if (o == null)            throw new NullPointerException();        if (!obs.contains(o)) {            obs.addElement(o);        }    }    /**     *      * 从该对象的观察者集中删除观察者。将 null 传递给此方法将不起作用。     * @param   o   the observer to be deleted.     */    public synchronized void deleteObserver(Observer o) {        obs.removeElement(o);    }    /**     *      * 如果此对象已更改,如 hasChanged 方法所示,则通知其所有观察者,然后调用 clearChanged 方法以指示此对象不再      * 更改。      * 每个观察者都使用两个参数调用 update 方法:observable对象和 null 。换句话说,此方法等效于:      * notifyObservers(null)     * @see     java.util.Observable#clearChanged()     * @see     java.util.Observable#hasChanged()     * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)     */    public void notifyObservers() {        notifyObservers(null);    }    /**     *      * 如果此对象已更改,如 hasChanged 方法所示,则通知其所有观察者,然后调用 clearChanged 方法以指示此对象不再      * 更改。      * 每个观察者都使用两个参数调用 update 方法:observable对象和 arg 参数。     * @param   arg   any object.     * @see     java.util.Observable#clearChanged()     * @see     java.util.Observable#hasChanged()     * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)     */    public void notifyObservers(Object arg) {        /*         *          * 临时数组缓冲区,用作当前Observers状态的快照。         */        Object[] arrLocal;        synchronized (this) {            /*              * 我们不希望Observer在拥有自己的Monitor时进行任意代码的回调。我们从Vector中提取每个Observable并存              * 储Observer状态的代码需要同步,但是通知观察者不会(不应该)。这里任何潜在竞争条件的最坏结果是:             * 1)新添加的观察者将错过正在进行的通知             * 2)最近未注册的观察者将被错误地通知             */            if (!changed)                return;            arrLocal = obs.toArray();            clearChanged();        }        for (int i = arrLocal.length-1; i>=0; i--)            ((Observer)arrLocal[i]).update(this, arg);    }    /**     *      * 清除观察者列表,以便此对象不再具有任何观察者。     */    public synchronized void deleteObservers() {        obs.removeAllElements();    }    /**     *      * 将此 Observable 对象标记为已更改;  hasChanged 方法现在将返回 true 。     */    protected synchronized void setChanged() {        changed = true;    }    /**     *      * 表示此对象已不再更改,或者已向其所有观察者通知其最近的更改,因此 hasChanged 方法现在将返回 false 。     * 此方法由 notifyObservers 方法自动调用。     * @see     java.util.Observable#notifyObservers()     * @see     java.util.Observable#notifyObservers(java.lang.Object)     */    protected synchronized void clearChanged() {        changed = false;    }    /**     *      * 测试此对象是否已更改。     * @return  true if and only if the setChanged     *          method has been called more recently than the     *          clearChanged method on this object;     *          false otherwise.     * @see     java.util.Observable#clearChanged()     * @see     java.util.Observable#setChanged()     */    public synchronized boolean hasChanged() {        return changed;    }    /**     *      * 返回此 Observable 对象的观察者数。     * @return  the number of observers of this object.     */    public synchronized int countObservers() {        return obs.size();    }}

Java源码使用Vector,Vector相比于ArrayList来说,它是线程安全的。在添加和删除观察者时对两个方法使用了synchronized关键字,这都是在为多线程考虑。

观察者:实现观察者接口(java.util.Observer),然后调用任何Observable对象的addObserver()方法,注销观察者时,就调用deleteObserver()方法即可。

第一个观察者对象:

public class XinhuaNewsAgency implements Observer {    //被观察者对象    private Observable observable;    public XinhuaNewsAgency(Observable observable) {        this.observable = observable;        //将观察者对象加入到观察者集合中        observable.addObserver(this);    }    @Override    public void update(Observable o, Object arg) {        if(o instanceof Repoter){            System.out.println("新华社发布最新报道:" + ((Repoter) o).getMsg());        }    }    public void remove(){        //删除观察者        observable.deleteObserver(this);    }}

第二个观察者对象:

public class PeopleDaily implements Observer {        //被观察者对象    private Observable observable;    public PeopleDaily(Observable observable) {        this.observable = observable;        //将观察者对象加入到观察者集合中        observable.addObserver(this);    }    @Override    public void update(Observable o, Object arg) {        if (o instanceof Repoter){            System.out.println("人民日报发布最新报道:" + ((Repoter) o).getMsg());        }    }    public void remove(){        //删除观察者        observable.deleteObserver(this);    }}

第三个观察者对象:

public class NewsFeeds implements Observer {    //被观察对象    private Observable observable;    public NewsFeeds(Observable observable) {        this.observable = observable;        //将观察者对象加入到观察者集合中        observable.addObserver(this);    }    @Override    public void update(Observable o, Object arg) {        if (o instanceof Repoter){            System.out.println("新闻联播发布最新报道:" + ((Repoter) o).getMsg());        }    }    public void remove(){        //删除观察者        observable.deleteObserver(this);    }}

被观察者:继承java.util.Observable类,调用setChanged()方法,标记状态改变。然后调用nofityObservers()方法或者notifyobservers(Object arg) 方法。

public class Repoter extends Observable {    private String msg;    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;        this.setChanged();        this.notifyObservers(msg);    }}

测试:

public class TestDemo {    @Test    public void demo(){        Repoter repoter = new Repoter();        NewsFeeds newsFeeds = new NewsFeeds(repoter);        PeopleDaily peopleDaily = new PeopleDaily(repoter);        XinhuaNewsAgency xinhuaNewsAgency = new XinhuaNewsAgency(repoter);        repoter.setMsg("为实现中华民族伟大复兴而奋斗!!!");    }}

结果:

新华社发布最新报道:为实现中华民族伟大复兴而奋斗!!!人民日报发布最新报道:为实现中华民族伟大复兴而奋斗!!!新闻联播发布最新报道:为实现中华民族伟大复兴而奋斗!!!Process finished with exit code 0

结果发现顺序和注册的顺序并不一致。将新闻联播注销,在运行:

public class TestDemo {    @Test    public void demo(){        Repoter repoter = new Repoter();        NewsFeeds newsFeeds = new NewsFeeds(repoter);        PeopleDaily peopleDaily = new PeopleDaily(repoter);        XinhuaNewsAgency xinhuaNewsAgency = new XinhuaNewsAgency(repoter);        repoter.setMsg("为实现中华民族伟大复兴而奋斗!!!");        newsFeeds.remove();        System.out.println("------------------------------------------------");        repoter.setMsg("华为发布最新旗舰机Mate30系列型号手机");    }}

结果:

新华社发布最新报道:为实现中华民族伟大复兴而奋斗!!!人民日报发布最新报道:为实现中华民族伟大复兴而奋斗!!!新闻联播发布最新报道:为实现中华民族伟大复兴而奋斗!!!------------------------------------------------新华社发布最新报道:华为发布最新旗舰机Mate30系列型号手机人民日报发布最新报道:华为发布最新旗舰机Mate30系列型号手机Process finished with exit code 0

劣势:

Observable是一个类,而不是一个接口,导致Observable类的扩展性不高,不如自己实现的观察者模式灵活。
Observable将某些方法保护了起来(setChanged()和clearChanged()为protected),这意味着除非继承自Observable,否则将有关键的方法不能调用。导致无法通过组合的方式使其它类获得Observable类的功能。

看完上述内容,你们对JAVA的观察者模式的作用是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

观察 观察者 对象 方法 最新报道 伟大 中华民族 民族 角色 中华 复兴 主题 接口 模式 状态 人民 新闻 新闻联播 日报 人民日报 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网金融科技 百单网互联网科技有限公司怎么样 苏州找大状互联网科技有限公司 高科技互联网 互联网金融与金融科技 互联网科技的未来发展 互联网科技公司有哪些 互联网科技素材视频竖屏 湖南洣水互联网科技有限公司扣款 消费医药和互联网科技 洛阳共同富裕互联网科技有限公司 中和天地互联网科技有限公司 上海京穆互联网科技有限公司 高科技互联网套路 广东工业互联网大赛深圳学泰科技 互联网领先科技宣传片 从那以后互联网科技有限公司 云鲸互联网络科技有限公司 上海万顺科技互联网有限公司招聘 山东蛋芒互联网科技有限公司 中国互联网科技工作委员会毛军 今日互联网科技 互联网科技深圳 互联网为科技 无线互联网科技 海南购全球互联网科技 互联网科技博主是什么意思 栖莱科技互联网股份有限公司 互联网科技和信息 雨阳互联网卡科技有限公司
0