实例代码讲解JAVA 观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

介绍

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

关键代码:在抽象类里有一个 ArrayList 存放观察者们。

应用实例:

1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。

2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

优点:

1、观察者和被观察者是抽象耦合的。

2、建立一套触发机制。

缺点:

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项:

1、JAVA 中已经有了对观察者模式的支持类。

2、避免循环引用。

3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

实现

观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。

ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。

步骤 1

创建 Subject 类。

import java.util.ArrayList;
import java.util.List;

public class Subject {

  private List<Observer> observers
   = new ArrayList<Observer>();
  private int state;

  public int getState() {
   return state;
  }

  public void setState(int state) {
   this.state = state;
   notifyAllObservers();
  }

  public void attach(Observer observer){
   observers.add(observer);
  }

  public void notifyAllObservers(){
   for (Observer observer : observers) {
     observer.update();
   }
  }
}

步骤 2

创建 Observer 类。

public abstract class Observer {
  protected Subject subject;
  public abstract void update();
}

步骤 3

创建实体观察者类。

public class BinaryObserver extends Observer{

  public BinaryObserver(Subject subject){
   this.subject = subject;
   this.subject.attach(this);
  }

  @Override
  public void update() {
   System.out.println( "Binary String: "
   + Integer.toBinaryString( subject.getState() ) );
  }
}
public class OctalObserver extends Observer{

  public OctalObserver(Subject subject){
   this.subject = subject;
   this.subject.attach(this);
  }

  @Override
  public void update() {
   System.out.println( "Octal String: "
   + Integer.toOctalString( subject.getState() ) );
  }
}
public class HexaObserver extends Observer{

  public HexaObserver(Subject subject){
   this.subject = subject;
   this.subject.attach(this);
  }

  @Override
  public void update() {
   System.out.println( "Hex String: "
   + Integer.toHexString( subject.getState() ).toUpperCase() );
  }
}

步骤 4

使用 Subject 和实体观察者对象。

public class ObserverPatternDemo {
  public static void main(String[] args) {
   Subject subject = new Subject();

   new HexaObserver(subject);
   new OctalObserver(subject);
   new BinaryObserver(subject);

   System.out.println("First state change: 15");
   subject.setState(15);
   System.out.println("Second state change: 10");
   subject.setState(10);
  }
}

步骤 5

执行程序,输出结果:

First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010

以上就是实例代码讲解JAVA 观察者模式的详细内容,更多关于JAVA 观察者模式的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java回调函数与观察者模式实例代码

    本文研究的主要是Java回调函数与观察者模式的实现,具体介绍和实现代码如下. 观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式.模型-视图(View)模式.源-收听者(Listener)模式或从属者模式)是软件设计模式的一种.在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来实现事件处理系统. 什么时候使用观察者模式: 当一个抽象模型有两个方面, 其中一个方面依

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

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

  • Java设计模式之观察者模式原理与用法详解

    本文实例讲述了Java设计模式之观察者模式原理与用法.分享给大家供大家参考,具体如下: 什么是观察者模式 可以这么理解: 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己. 也可以这样理解: 观察者模式是关于多个对象想知道一个对象中数据变化情况的一种成熟模式.观察者模式中有一个称作"主题"的对象和若干个称作"观察者"的对象,"主题"和&qu

  • Java使用观察者模式实现气象局高温预警功能示例

    本文实例讲述了Java使用观察者模式实现气象局高温预警功能.分享给大家供大家参考,具体如下: 一.模式定义 观察者模式,又称为发布/订阅模式.观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 二.模式举例 1 模式分析 我们借用气象局高温预警来说明这一模式. 2 观察者模式静态类图 3 代码示例 3.1观察者接口一IObserver package com.demo.observer; import com.demo.subje

  • Java设计模式—观察者模式详解

    观察者模式 包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承,学的时候应该 记得归纳,记得本文最开始的那个图.观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你.其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系. 先来看看关系图: 我解释下这些类的作用:MySubject类就是我们的主对象,Obs

  • JAVA中常用的设计模式:单例模式,工厂模式,观察者模式

    1.单例模式 每个类只能创建一个实例对象 Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection). 好处: 第一.控制资源的使用,通过线程同步来控制资源的并发访问: 第二.控制实例产生的数量,达到节约资源的目的. 第三.作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程

  • java使用观察者模式异步短信/邮箱提醒用户群

    需求 用户中有人设置了账户余额达到阈值时,短信/邮箱进行提醒的服务.我们将需要在他账户余额阈值达到指定数值的时候进行短信/邮箱消息通知,允许账户余额阈值出现偏差的时候通知,如果某个用户48小时内已经短信/邮箱进行过通知了,那么将不再进行通知. 剖析 存在两个主题:短信通知和邮箱通知 存在两种观察者:设置了短信通知且账户余额到达阈值的用户,设置了邮箱通知且账户余额到达阈值的用户. 用spring的定时器,每10分钟去数据库获取某个主题已经达到阈值且开始了该主题的提醒功能的用户 用spring的@A

  • 23种设计模式(13)java观察者模式

    23种设计模式第十三篇:java观察者模式 定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新. 类型:行为类模式 类图: 在软件系统中经常会有这样的需求:如果一个对象的状态发生改变,某些与它相关的对象也要随之做出相应的变化.         比如,我们要设计一个右键菜单的功能,只要在软件的有效区域内点击鼠标右键,就会弹出一个菜单:         再比如,我们要设计一个自动部署的功能,就像eclipse开发时,只要修改了文件,eclips

  • 实例代码讲解JAVA 观察者模式

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

  • 实例代码讲解JAVA多线程

    进程与线程 进程是程序的一次动态执行过程,它需要经历从代码加载,代码执行到执行完毕的一个完整的过程,这个过程也是进程本身从产生,发展到最终消亡的过程.多进程操作系统能同时达运行多个进程(程序),由于 CPU 具备分时机制,所以每个进程都能循环获得自己的CPU 时间片.由于 CPU 执行速度非常快,使得所有程序好像是在同时运行一样. 多线程是实现并发机制的一种有效手段.进程和线程一样,都是实现并发的一个基本单位.线程是比进程更小的执行单位,线程是进程的基础之上进行进一步的划分.所谓多线程是指一个进

  • Spring boot + mybatis + orcale实现步骤实例代码讲解

    接着上次的实现, 添加 mybatis 查询 orcale 数据库 第一步: 新建几个必须的包, 结果如下 第二步: 在service包下新建personService.java 根据名字查person方法接口 package com.example.first.service; import com.example.first.entity.Person; public interface personService { Person queryPersonByName(String name

  • ASP.NET操作MySql数据库的实例代码讲解

    一.把MySql.Data.dll放到BIN目录下. 二.这是aspx.cs的全部源码,修改参数直接运行即可!   using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; publ

  • jQuery判断邮箱格式对错实例代码讲解

    废话不多说了,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>检测Email地址格式是否正确</title> <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"><

  • JS实现JSON.stringify的实例代码讲解

    JSON.stringify是浏览器高版本带的一个将JS的Objtect对象转换为JSON字符串的一个方法,不过再IE6下面,并不存在JSON这一对象,因此,用到此方法时,需要写一套兼容性的代码. JSON.stringify的一些规则以及注意点:当对象为数字,null,boolean的时候,直接转换为相应的字符串就可以了. 但是string,function,undefined,object,array等,需要特殊处理. 1.undefined,该类型使用JSON.stringify处理的时候

  • Android Dialog对话框实例代码讲解

    Dialog的基本方法 //创建Dialog AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); //设置标题图标 builder.setIcon(R.drawable.ic_launcher); //设置标题 builder.setTitle("这是一个对话框"); //设置信息 builder.setMessage("是否要跳转?"); //确定按钮 setPosit

  • vue slot与传参实例代码讲解

    插槽分为默认插槽和具名插槽: 默认插槽: //父组件 <div> <h3>父组件</h3> <testChild> <div>默认插槽</div> </testChild> </div> //子组件 <div> <h4>子组件</h4> <slot></slot> </div> 具名插槽: 注意:具名插槽需要包裹在  template  标

  • 实例代码讲解c# 线程(下)

    前言 实例代码讲解c# 线程(上) 使用Mutex类 class Program { static void Main(string[] args) { const string MutexName ="CSharpThreadingCookbook"; using (var m = new Mutex(false, MutexName)) { if (!m.WaitOne(TimeSpan.FromSeconds(5), false)) { Console.WriteLine(&qu

  • 实例代码讲解c++ 继承特性

    --派生类需要自己的构造函数. 派生类中可以根据需要添加额外的数据成员和成员函数,甚至可以给予继承的原成员函数新的定义. 基类指针或引用可指向派生对象,反过来则只能使用强制类型转换. 派生类对象可使用基类的非私有成员. 可使用派生对象初始化基类对象或赋值. 一般不允许将基类对象赋给派生类对象(上面第三条),特殊情况下可以. 已有派生类对象初始化创建的派生类对象. 已有派生类对象给另一个派生类对象赋值. 派生类对象的析构函数被调用后会自动调用基类的析构函数. C++11增加了允许继承构造函数的机制

随机推荐