当前位置: 首页 > 编程笔记 >

Java中的观察者模式实例讲解

齐永昌
2023-03-14
本文向大家介绍Java中的观察者模式实例讲解,包括了Java中的观察者模式实例讲解的使用技巧和注意事项,需要的朋友参考一下

观察者模式是一种行为设计模式。观察者模式的用途是,当你对一个对象的状态感兴趣,希望在它每次发生变化时获得通知。在观察者模式中,观察另外一个对象状态的对象叫做Observer观察者,被观察的对象叫着Subject被观察者。根据GoF规则,观察者模式的意图是:


定义对象之间一对多的依赖关系,一个对象状态改变,其他相关联的对象就会得到通知并被自动更新。

Subject(被观察者)包含了一些需要在其状态改变时通知的观察者。因此,他应该提供给观察者可以register(注册)自己和unregister(注销)自己的方法。当Subject(被观察者)发生变化的时候,也需要包含一个方法来通知所有观察者。当通知观察者的时候,可以推送更新内容,或者提供另外一个方法来获得更新内容。

观察者应该有一种方法,这种方法能够设置观察者对象并且可以由被观察者使用来通知其更新。

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

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<Observer> 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<Observer> 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</pre>

观察者模式的UML图

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

1.Swing 中的 java.util.EventListener
2.javax.servlet.http.HttpSessionBindingListener
3.javax.servlet.http.HttpSessionAttributeListener

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

 类似资料:
  • 本文向大家介绍C#设计模式之观察者模式实例讲解,包括了C#设计模式之观察者模式实例讲解的使用技巧和注意事项,需要的朋友参考一下 前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高、保证代码可靠性。所谓设计模式,我找了下定义:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软

  • 本文向大家介绍php中的观察者模式简单实例,包括了php中的观察者模式简单实例的使用技巧和注意事项,需要的朋友参考一下 观察者模式是设计模式中比较常见的一个模式,包含两个或者更多的互相交互的类。这一模式允许某个类观察另外一个类的状态,当被观察类的状态发生变化时候,观察者会进行得到通知进而更新相应状态。 php的SPL标准类库提供了SplSubject和SplObserver接口来实现,被观察的类叫

  • 主要内容:介绍,实现,Subject.java,Observer.java,BinaryObserver.java,OctalObserver.java,HexaObserver.java,ObserverPatternDemo.java当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。 介绍 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知

  • 观察者模式 亦称: 事件订阅者、监听者、Event-Subscriber、Listener、Observer 意图 观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。 问题 假如你有两种类型的对象: ​ 顾客和 商店 。 顾客对某个特定品牌的产品非常感兴趣 (例如最新型号的 iPhone 手机), 而该产品很快将会在商店里出售。 顾客

  • 一、定义 观察者模式(发布-订阅模式):其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。 在JavaScript中,一般使用事件模型来替代传统的观察者模式。 好处: (1)可广泛应用于异步编程中,是一种替代传递回调函数的方案。 (2)可取代对象之间硬编码的通知机制,一个对象不用再显示地调用另外一个对象的某个接口。两对象轻松解耦。 二、DOM事件–观察者

  • 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。 介绍 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。 何时使用:一个对象(目标对象)