Java设计模式开发中使用观察者模式的实例教程_java

观察者模式是软件设计模式中的一种,使用也比较普遍,尤其是在GUI编程中。关于设计模式的文章,网络上写的都比较多,而且很多文章写的也不错,虽然说有一种重复早轮子的嫌疑,但此轮子非彼轮子,侧重点不同,思路也不同,讲述方式也不近相同。
关键要素

主题:

主题是观察者观察的对象,一个主题必须具备下面三个特征。

  • 持有监听的观察者的引用
  • 支持增加和删除观察者
  • 主题状态改变,通知观察者

观察者:

当主题发生变化,收到通知进行具体的处理是观察者必须具备的特征。

为什么要用这种模式

这里举一个例子来说明,牛奶送奶站就是主题,订奶客户为监听者,客户从送奶站订阅牛奶后,会每天收到牛奶。如果客户不想订阅了,可以取消,以后就不会收到牛奶。

松耦合

观察者增加或删除无需修改主题的代码,只需调用主题对应的增加或者删除的方法即可。
主题只负责通知观察者,但无需了解观察者如何处理通知。举个例子,送奶站只负责送递牛奶,不关心客户是喝掉还是洗脸。
观察者只需等待主题通知,无需观察主题相关的细节。还是那个例子,客户只需关心送奶站送到牛奶,不关心牛奶由哪个快递人员,使用何种交通工具送达。

Java实现观察者模式
1. Java自带的实现
类图

/**
 * 观察目标 继承自 java.util.Observable
 * @author stone
 *
 */
public class UpdateObservable extends Observable { 

  private int data; 

  public UpdateObservable(Observer observer) {
    addObserver(observer);
    /*
     * add other observer
     */
  } 

  public int getData() {
    return data;
  } 

  public void setData(int data) {
    if (data != this.data) {
      this.data = data;
      setChanged(); //标记 改变, 只有标记后才能通知到
      notifyObservers(); //通知
    } 

  } 

  @Override
  public synchronized void addObserver(Observer o) {
    super.addObserver(o);
  } 

  @Override
  public synchronized void deleteObserver(Observer o) {
    super.deleteObserver(o);
  } 

  @Override
  public void notifyObservers() {
    super.notifyObservers();
  } 

  @Override
  public void notifyObservers(Object arg) {
    super.notifyObservers(arg);
  } 

  @Override
  public synchronized void deleteObservers() {
    super.deleteObservers();
  } 

  @Override
  protected synchronized void setChanged() {
    super.setChanged();
  } 

  @Override
  protected synchronized void clearChanged() {
    super.clearChanged();
  } 

  @Override
  public synchronized boolean hasChanged() {
    return super.hasChanged();
  } 

  @Override
  public synchronized int countObservers() {
    return super.countObservers();
  } 

} 
/**
 * 观察者 实现 java.util.Observer接口
 * @author stone
 *
 */
public class UpdateObserver implements Observer { 

  @Override
  public void update(Observable o, Object arg) {
    System.out.println("接收到数据变化的通知:");
    if (o instanceof UpdateObservable) {
      UpdateObservable uo = (UpdateObservable) o;
      System.out.print("数据变更为:" + uo.getData());
    }
  } 

} 

2. 自定义的观察模型
类图

/**
 * 抽象观察者  Observer
 * 观察 更新
 * @author stone
 *
 */
public interface IWatcher {
  /*
   * 通知接口:
   * 1. 简单通知
   * 2. 观察者需要目标的变化的数据,那么可以将目标用作参数, 见Java的Observer和Observable
   */
// void update(IWatched watched); 

  void update(); 

} 
/**
 * 抽象目标 Subject
 * 提供注册和删除观察者对象的接口, 及通知观察者进行观察的接口
 * 及目标 自身被观察的业务的接口
 * @author stone
 *
 */
public interface IWatchedSubject { 

  public void add(IWatcher watch); 

  public void remove(IWatcher watch); 

  public void notifyWhatchers(); 

  public void update();//被观察业务变化的接口
} 
/**
 * 具体观察者    Concrete Observer
 *
 * @author stone
 *
 */
public class UpdateWatcher implements IWatcher { 

  @Override
  public void update() {
    System.out.println(this + "观察到:目标已经更新了");
  } 

}
/**
 * 具体目标角色  Concrete Subject
 * @author stone
 *
 */
public class UpdateWatchedSubject implements IWatchedSubject {
  private List<IWatcher> list; 

  public UpdateWatchedSubject() {
    this.list = new ArrayList<IWatcher>();
  } 

  @Override
  public void add(IWatcher watch) {
    this.list.add(watch);
  } 

  @Override
  public void remove(IWatcher watch) {
    this.list.remove(watch);
  } 

  @Override
  public void notifyWhatchers() {
    for (IWatcher watcher : list) {
      watcher.update();
    }
  } 

  @Override
  public void update() {
    System.out.println("目标更新中....");
    notifyWhatchers();
  } 

}

监听器是观察者的一种实现:
类图

/**
 * 监听 用户在注册后
 * @author stone
 *
 */
public interface IRegisterListener {
  void onRegistered();
} 
/**
 * 监听 当用户登录后
 * @author stone
 *
 */
public interface ILoginListener {
  void onLogined();
} 
/*
 * 监听器 是观察者模式的一种实现
 * 一些需要监听的业务接口上添加 监听器,调用监听器的相应方法,实现监听
 */
public class User { 

  public void register(IRegisterListener register) {
    /*
     * do ... register
     */
    System.out.println("正在注册中...");
    //注册后
    register.onRegistered();
  } 

  public void login(ILoginListener login) {
    /*
     * do ... login
     */
    System.out.println("正在登录中...");
    //登录后
    login.onLogined();
  } 

}
/**
 * 观察者(Observer)模式 行为型模式
 *  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时观察某一个目标对象。
 *  这个目标对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己
 * 目标对象中需要有添加、移除、通知 观察者的接口
 *
 * @author stone
 */
public class Test { 

  public static void main(String[] args) {
    /*
     * 使用Java自带的Observer接口和Observable类
     */
    UpdateObservable observable = new UpdateObservable(new UpdateObserver());
    observable.setData(99);
    System.out.println("");
    System.out.println("");
    /*
     * 自定义的观察者模型
     */
    IWatchedSubject watched = new UpdateWatchedSubject();
    watched.add(new UpdateWatcher());
    watched.add(new UpdateWatcher());
    watched.update();
    System.out.println(""); 

    /*
     * 子模式-监听器
     */ 

    User user = new User();
    user.register(new IRegisterListener() { 

      @Override
      public void onRegistered() {
        System.out.println("监听到注册后。。。");
      }
    });
    user.login(new ILoginListener() { 

      @Override
      public void onLogined() {
        System.out.println("监听到登录后。。。");
      }
    }); 

  }
}

打印

接收到数据变化的通知:
数据变更为:99 

目标更新中....
observer.UpdateWatcher@457471e0观察到:目标已经更新了
observer.UpdateWatcher@5fe04cbf观察到:目标已经更新了 

正在注册中...
监听到注册后。。。
正在登录中...
监听到登录后。。。 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 设计模式
观察者模式
java观察者模式实例、js 观察者模式 实例、观察者模式实例、php 观察者模式实例、观察者模式的实例,以便于您获取更多的相关知识。

时间: 2024-10-31 07:30:12

Java设计模式开发中使用观察者模式的实例教程_java的相关文章

实例解析观察者模式及其在Java设计模式开发中的运用_java

一.观察者模式(Observer)的定义: 观察者模式又称为订阅-发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来事件处理系统. 1.观察者模式的一般结构 首先看下观察者模式的类图描述: 观察者模式的角色如下: Subject(抽象主题接口):定义了主题类中对观察者列表的一系列操作, 包括增加,删除, 通知等. Concrete Subject(具体主题类): Observer(抽象

实例解析Ruby设计模式开发中对观察者模式的实现_ruby专题

一般来说,观察者模式的定义应该是这样的:building a clean interface between the source of news that some object has changed and the consumers of that news. 观察者模式在消息的生产者和消费者之间建立了clean interface,这样就使得消息的生产者和消费者之间的耦合是抽象的.被观察者可以不认识任何一个的观察者,它只知道他们都实现了一个共同的接口.由于观察者和被观察者没有紧密的耦合

java开发中基于JDBC连接数据库实例总结_java

本文实例讲述了java开发中基于JDBC连接数据库的方法.分享给大家供大家参考,具体如下: 创建一个以JDBC连接数据库的程序,包含7个步骤:   1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String  className)实现. 例如: try{ //加载MySql的驱动类 Class.forName("com.mysql.jdbc.Driver") ;

JavaScript设计模式开发中组合模式的使用教程_基础知识

我们平时开发过程中,一定会遇到这种情况:同时处理简单对象和由简单对象组成的复杂对象,这些简单对象和复杂对象会组合成树形结构,在客户端对其处理的时候要保持一致性.比如电商网站中的产品订单,每一张产品订单可能有多个子订单组合,比如操作系统的文件夹,每个文件夹有多个子文件夹或文件,我们作为用户对其进行复制,删除等操作时,不管是文件夹还是文件,对我们操作者来说是一样的.在这种场景下,就非常适合使用组合模式来实现. 基本知识 组合模式:将对象组合成树形结构以表示"部分-整体"的层次结构,组合模式

Java UI开发中工具包 Swing intro 实例

Swing工具包跟Android app开发的UI方面有相似的地方.本文我们来介绍一下Swing. 先用代码就能抛出一个框框,记录一下操作过程 1.先显示一个框框 EraseBlockGame类是主类,包含了main入口,继承自 JFrame public class EraseBlockGame extends JFrame{ ......     public EraseBlockGame(String GameTitle){  // 构造方法         super(GameTitle

Java实现AOP面向切面编程的实例教程_java

介绍 众所周知,AOP(面向切面编程)是Spring框架的特色功能之一.通过设置横切关注点(cross cutting concerns),AOP提供了极高的扩展性.那AOP在Spring中是怎样运作的呢?当你只能使用core java,却需要AOP技术时,这个问题的解答变得极为关键.不仅如此,在高级技术岗位的面试中,此类问题也常作为考题出现.这不,我的朋友最近参加了一个面试,就被问到了这样一个棘手的问题--如何在不使用Spring及相关库,只用core Java的条件下实现AOP.因此,我将在

Java多线程编程中synchronized线程同步的教程_java

0.关于线程同步 (1)为什么需要同步多线程?线程的同步是指让多个运行的线程在一起良好地协作,达到让多线程按要求合理地占用释放资源.我们采用Java中的同步代码块和同步方法达到这样的目的.比如这样的解决多线程无固定序执行的问题: public class TwoThreadTest { public static void main(String[] args) { Thread th1= new MyThread1(); Thread th2= new MyThread2(); th1.sta

Java游戏开发中应始终坚持的10项基本原则

关于文章中涉及的两个杜撰概念: 一.绘图器:众所周知,Java GUI以paint进行绘图,以repaint进行图像刷新,而完成repaint及paint这一连贯过程中所用到绘图组件,我将其称为绘图器.就我个人的体会,绘图器的调用时机应始终处于repaint之后paint之前,即通过repaint触发刷新后执行,当其中的具体逻辑完成其对应的图像绘制后,再通过统一接口将其图像插入paint中,为了匹配需要,绘图器应始终以接口方式实现. 二.监听器:这里所说的监听器,并不是特指某个Listener组

安卓开发中Bitmap源码实例

 安卓开发中Bitmap源码实例 package android.graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; public final class Bitmap extends _Original_Bitmap { private Bu