java 观察者_JAVA中的观察者模式实例教程

观察者模式例子

在此例中,我们将完成一个简单的主题讨论,观察者能够注册此主题。任何在此主题上的内容提交导致的变化都会通知所有在注册的观察者。

基于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 message

Message Posted to Topic:New Message

Obj1:: Consuming message::New Message

Obj2:: Consuming message::New Message

Obj3:: Consuming message::New Message

观察者模式的UML图

387445452298386c9c4d2949eaa94e3d.png

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

Swing 中的 java.util.EventListener

javax.servlet.http.HttpSessionBindingListener

javax.servlet.http.HttpSessionAttributeListener

以上为全部的观察者模式。希望你已经喜欢上它了。在评论中分享你的感受或者请分享给其他人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值