千家信息网

Java的观察者模式的实现方法

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,这篇文章主要讲解了"Java的观察者模式的实现方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java的观察者模式的实现方法"吧!观察者模式又称为发
千家信息网最后更新 2025年01月31日Java的观察者模式的实现方法

这篇文章主要讲解了"Java的观察者模式的实现方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java的观察者模式的实现方法"吧!

观察者模式又称为发布/订阅(Publish/Subscribe)模式,观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

观察者(Observer)相当于事件监听者,被观察者(Observable)相当于事件源和事件,将观察者和被观察者的对象分离开,提高了应用程序的可维护性和重用性。执行逻辑时通知observer即可触发oberverupdate,同时可传被观察者和参数。

观察者Observer:所有潜在的观察者必须实现观察者接口,这个接口只有update方法,当主题改变时,它被调用。

具体观察者ConcreteObserver: 具体观察者可以是任何实现了Observer接口的类。观察者必须注册具体主题,一边接收更新。

可观察者Subject: 主题接口,即可观察者Observable,对象使用此接口注册为观察者,或者把自己从观察者中删除,每个主题可以有多个观察者。

具体可观察者ConcreteSubject: 一个具体主题实现了主题接口,除了注册和撤销之外,具体主题还实现了notifyObservers()方法,这个方法用来在主题状态改变时更新所有观察者。具体主题也可能有设置和获取状态的方法。

Subject(被观察者)包含了一些需要在其状态改变时通知的观察者。因此,他应该提供给观察者可以register(注册)自己和unregister(注销)自己的方法。当Subject(被观察者)发生变化的时候,也需要包含一个方法来通知所有观察者。当通知观察者的时候,可以推送更新内容,或者提供另外一个方法来获得更新内容。参考资料:https://www.javacodegeeks.com/2013/08/observer-design-pattern-in-java-example-tutorial.html

JAVA提供了内置的方式来实现观察者模式,java.util.Observablejava.util.Observer接口。然而他们用的不是很广泛。因为此实现过于简单,大多数时候我们都不想最后扩展的类仅仅是实现了观察者模式,因为JAVA类不能多继承。

观察者模式的UML图

Java Messages Service(JMS)消息服务使用观察者模式与命令模式来实现不同的程序之间的数据的发布和订阅。MVC模型-视图-控制框架也使用观察者模式,把模型当做被观察者,视图视为观察者。视图能够注册自己到模型上来获得模型的改变。

观察者模式实例

在此实例中,将完成一个简单的主题讨论,观察者能够注册此主题。任何在此主题上的内容提交导致的变化都会通知所有注册的观察者。基于Subject被观察者的需求,这个是实现一个基本的Subject接口,此接口定了一系列具体的方法需要在随后实现接口的具体类中被实现。

package com.journaldev.design.observer;

public interface Subject {

//methods to register and unregister observers

public void register(Observer obj);

public void unregister(Observer obj);

//method to notify observers of change

public void notifyObservers();


//method to get updates from subject

public Object getUpdate(Observer obj);

}

现在创建一个相关联的观察者。它需要有一个方法能使Subject附属于一个观察者。另外的方法能够接受Subject的变化通知。

package com.journaldev.design.observer; public interface Observer {        //method to update the observer, used by subject    public void update();        //attach with subject to observe    public void setSubject(Subject sub);    }

这种关联已经建立。现在实现具体的主题。

package com.journaldev.design.observer;import java.util.ArrayList;import java.util.List;public class MyTopic implements Subject {        private List observers;        private String message;        private boolean changed;        private final Object MUTEX= new Object();        public MyTopic(){            this.observers=new ArrayList<>();        }        @Override    public void register(Observer obj) {            if(obj == null) throw new NullPointerException("Null Observer");            if(!observers.contains(obj)) observers.add(obj);        }        @Override    public void unregister(Observer obj) {            observers.remove(obj);        }        @Override    public void notifyObservers() {            List observersLocal = null;            //synchronization is used to make sure any observer registered after message is received is not notified        synchronized (MUTEX) {                if (!changed)                   return;            observersLocal = new ArrayList<>(this.observers);            this.changed=false;            }            for (Observer obj : observersLocal) {            obj.update();        }    }        @Override    public Object getUpdate(Observer obj) {        return this.message;    }        //method to post message to the topic    public void postMessage(String msg){        System.out.println("Message Posted to Topic:"+msg);        this.message=msg;        this.changed=true;        notifyObservers();        }    }

注册与注销观察者方法的实现非常简单,额外的方法postMessage()将被客户端应用来提交一个字符串消息给此主题。注意,布尔变量用于追踪主题状态的变化并且通知观察者此种变化。这个变量是必须的,因为如果没有更新,但是有人调用notifyObservers()方法,他就不能发送错误的通知信息给观察者。

此外需要注意的是,notifyObservers()中使用synchronization同步的方式来确保在消息被发布给主题之前,通知只能被发送到注册的观察者处。此处是观察者的实现。他们将一直关注subject对象。

package com.journaldev.design.observer;public class MyTopicSubscriber implements Observer {        private String name;        private Subject topic;        public MyTopicSubscriber(String nm){        this.name=nm;    }        @Override    public void update() {            String msg = (String) topic.getUpdate(this);        if(msg == null){            System.out.println(name+":: No new message");        }else        System.out.println(name+":: Consuming message::"+msg);        }        @Override    public void setSubject(Subject sub) {        this.topic=sub;    }}

注意,update()方法的实现使用了被观察者的getUpdate()来处理更新的消息。此处应该避免把消息作为参数传递给update()方法。

下面是一个简单的测试程序来验证话题类的实现。

package com.journaldev.design.observer;public class ObserverPatternTest {    public static void main(String[] args) {            //create subject        MyTopic topic = new MyTopic();        //create observers        Observer obj1 = new MyTopicSubscriber("Obj1");        Observer obj2 = new MyTopicSubscriber("Obj2");        Observer obj3 = new MyTopicSubscriber("Obj3");        //register observers to the subject        topic.register(obj1);        topic.register(obj2);        topic.register(obj3);             //attach observer to subject        obj1.setSubject(topic);            obj2.setSubject(topic);        obj3.setSubject(topic);        //check if any update is available        obj1.update();                //now send message to subject        topic.postMessage("New Message");        }}

此处为上述输出内容:

Obj1:: No new messageMessage Posted to Topic:New MessageObj1:: Consuming message::New MessageObj2:: Consuming message::New MessageObj3:: Consuming message::New Message

观察者模式也被叫做发布订阅模式。JAVA中的一些具体应用如下:

Swing java.util.EventListenerjavax.servlet.http.HttpSessionBindingListenerjavax.servlet.http.HttpSessionAttributeListener

感谢各位的阅读,以上就是"Java的观察者模式的实现方法"的内容了,经过本文的学习后,相信大家对Java的观察者模式的实现方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0