全面解析Java观察者模式_java

【正文】

一、观察者模式的定义:

简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监听一个主题对象。这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。例如:GUI中的事件处理机制采用的就是观察者模式。

二、观察者模式的实现:

Subject(被观察的对象接口):规定ConcreteSubject的统一接口 ; 每个Subject可以有多个Observer;ConcreteSubject(具体被观察对象):维护对所有具体观察者的引用的列表 ;–状态发生变化时会发送通知给所有注册的观察者。Observer(观察者接口):规定ConcreteObserver的统一接口;定义了一个update()方法,在被观察对象状态改变时会被调用。ConcreteObserver(具体观察者):维护一个对ConcreteSubject的引用;特定状态与ConcreteSubject同步;实现Observer接口,update()方法的作用:一旦检测到Subject有变动,就更新信息。

图表描述如下:

注:在被观察者类中需要有一个集合维护所有观察者。

三、举例说明:

【方案一】:自己定义接口或者类来实现观察者模式。

步骤如下:

(1)定义被观察者所具有的接口:

package com.vince.observer;
public interface Observable {
 //注册为一个观察者
 public void registerObserver(Observer observer);

 //取消观察者
 public void removeObserver(Observer observer);

 //通知所有观察者更新信息
 public void notifyObservers();
}

(2)定义具体的被观察者:杯子

package com.vince.observer;
import java.util.Vector;

public class Cup implements Observable{
 //被观察者维护的一个观察者对象列表
 private Vector<Observer> vector = new Vector<Observer>();
 private float price;

 public Cup(float price){
  this.price = price;
 }

 public float getPrice() {
  return price;
 }
 public void setPrice(float price) {
  //修改价格时,通知所有观察者
  this.price = price;
  notifyObservers();
 }
 @Override
 public void registerObserver(Observer observer) {
  //注册观察者
  vector.add(observer);
 }
 @Override
 public void removeObserver(Observer observer) {
  //取消观察者
  vector.remove(observer);
 }
 @Override
 public void notifyObservers() {
  //实现通知所有的观察者对象
  for (Observer observer:vector) {
   observer.update(price);
  }
 }
}

(3)定义观察者所具有的共同的接口:(更新数据最终当然是在观察者那里进行啦)

package com.vince.observer;

public interface Observer {

  public void update(float price);5 

}

(4)定义具体的观察者对象:

package com.vince.observer;
public class Person implements Observer{
 private String name;
 public Person(String name){
  this.name = name;
 }
 @Override
 public void update(float price) {
  System.out.println(name+"关注的杯子的价格已更新为:"+price);
 }
}

(5)测试:

package com.vince.observer;
public class Test {
 public static void main(String[] args) {
  //创建一个被观察者对象
  Cup doll = new Cup(3000);
  //创建两个观察者对象
  Person p1 = new Person("生命壹号");
  Person p2 = new Person("生命贰号");
  //注册成为一个观察者
  doll.registerObserver(p1);
  doll.registerObserver(p2);

  System.out.println("第一轮促销:");
  doll.setPrice(2698);// 价格变动
  System.out.println("第二轮促销:");
  doll.setPrice(2299);//
  System.out.println("第三轮促销:");
  doll.setPrice(1998);

  doll.removeObserver(p2); //将生命二号移除
  System.out.println("第四轮促销:");
  doll.setPrice(1098);  

 }
}

运行后,显示结果如下:

【方案二】:直接调用JDK的API去实现。

步骤如下:

(1) 通过继承Observable类实现具体的被观察者对象:

package com.vince.observer2;
import java.util.Observable;

public class Cup extends Observable{
 private float price;

 public Cup(float price){
  this.price = price;
 }
 public float getPrice() {
  return price;
 }
 public void setPrice(float price) {
  this.price = price;
  this.setChanged();//通知,数据已改变
  this.notifyObservers();
 }

}

(2)通过实现java.util.Observer接口实现具体的观察者对象:

package com.vince.observer2;
import java.util.Observable;
import java.util.Observer;

public class Person implements Observer{
 private String name;
 public Person(String name){
  this.name = name;
 }
 @Override
 public void update(Observable o, Object arg) {
  if(o instanceof Cup){
   Cup cup = (Cup)o;
   System.out.println(name+"关注的杯子价格已更新为:"+cup.getPrice());
  }
 }
}

(3)测试:

package com.vince.observer2;
public class Test {
 public static void main(String[] args) {
  Cup cup = new Cup(3000);
  Person p1 = new Person("生命壹号");
  Person p2 = new Person("生命贰号");
  cup.addObserver(p1);
  cup.addObserver(p2);
  System.out.println("第一轮促销");
  cup.setPrice(2988);
  System.out.println("第二轮促销");
  cup.setPrice(2698);

  cup.deleteObserver(p2);
  System.out.println("第三轮促销");
  cup.setPrice(1998);
 }
}

运行后,结果如下:

【工程文件】

链接:http://xiazai.jb51.net/201609/yuanma/JavaSEguancha(jb51.net).rar

四、总结:(观察者模式的作用)

观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表。

由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。

观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

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

时间: 2024-11-03 18:23:39

全面解析Java观察者模式_java的相关文章

轻松掌握Java观察者模式_java

定义:当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知它的依赖对象. 特点:     1.观察者和被观察者是抽象耦合的.     2.建立一套触发机制. 企业级开发和常用框架中的应用:Java自带观察者类,servlet中的filter,分布式的消息队列 实例: public class Demo { public static void main(String[] args) { ActualSubject subject

全面解析Java8观察者模式_java

观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式,是四人组(GoF,即 Erich Gamma.Richard Helm.Ralph Johnson 和 John Vlissides)在1994合著的<设计模式:可复用面向对象软件的基础>中提出的(详见书中293-313页).尽管这种模式已经有相当长的历史,它仍然广泛适用于各种场景,甚至成为了标准Java库的一个组成部分.目前虽然已经有大量关于观察者模式的文章,但它们都专注于在 Java 中的实现,却忽视了

深入解析java虚拟机_java

java虚拟机是什么 "java虚拟机"可能指以下三种东西:1).抽象规范:2).一个具体的实现:3).一个运行中的虚拟机实例: java虚拟机生命周期 启动当启动一个java程序时,一个虚拟机实例诞生.虚拟机实例通过调用某个初始类的public static void main(String[] args)方法来运行一个java程序.任何拥有这样一个main方法的类都可以作为java程序运行的起点,所以必须要告诉虚拟机初始类的名称,整个程序将从它的main方法开始运行.消亡初始类的m

JDK的Parser来解析Java源代码详解_java

在JDK中,自带了一套相关的编译API,可以在Java中发起编译流程,解析Java源文件然后获取其语法树,在JDK的tools.jar(OSX下可以在/Library/Java/JavaVirtualMachines/jdk_version/Contents/Home/lib中找到)中包含着这整套API,但是这却不是Oracle和OpenJDK发布中的公开API,因此对于这套API,并没有官方的正式文档来进行说明.但是,也有不少项目利用了这套API来做了不少事情,例如大名鼎鼎的lombok使用了

深入解析Java中的内部类_java

概述 最近学习python,发现python是支持多继承的,这让我想起Java是通过内部类实现的这套机制.这篇文章不是讲如何通过内部类实现多继承,而是总结一下内部类的类型和使用方法. Java内部类分为:     非静态内部类     静态内部类     局部内部类     匿名内部类 内部类在Android源码中被大量的使用,先介绍一下这四种内部类的共同点:     内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号.     内部类不

深入解析Java中的数据类型与变量_java

Java数据类型转换(自动转换和强制转换)数据类型的转换,分为自动转换和强制转换.自动转换是程序在执行过程中"悄然"进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换:强制类型转换则必须在代码中声明,转换顺序不受限制. 自动数据类型转换 自动转换按从低到高的顺序转换.不同类型数据间的优先关系如下:     低--------------------------------------------->高     byte,short,char-> int

解析Java中的定时器及使用定时器制作弹弹球游戏的示例_java

  在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. 一.简介      在java中一个完整定时任务需要由Timer.TimerTask两个类来配合完成. API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.由TimerTask:Timer 安排为一次执行或重复执行的任务

深入解析Java的包(package)_java

虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备"对象"的特性--不携带属性.没有方法可调用. 沿用它们只是为了迎合人类根深蒂固的习惯,并的确能简单.有效地进行常规数据处理. 这种借助于非面向对象技术的做法有时也会带来不便,比如引用类型数据均继承了 Object 类的特性,要转换为 String 类型(经常有这种需要)时只要简单调用 Object 类中定义的toString()即可,而基本数据类型转换为 String 类型

深入解析Java接口(interface)的使用_java

Java接口(interface)的概念及使用 在抽象类中,可以包含一个或多个抽象方法:但在接口(interface)中,所有的方法必须都是抽象的,不能有方法体,它比抽象类更加"抽象". 接口使用 interface 关键字来声明,可以看做是一种特殊的抽象类,可以指定一个类必须做什么,而不是规定它如何去做. 现实中也有很多接口的实例,比如说串口电脑硬盘,Serial ATA委员会指定了Serial ATA 2.0规范,这种规范就是接口.Serial ATA委员会不负责生产硬盘,只是指定