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

 更新时间:2020年06月22日 15:37:10   作者:菜鸟教程  
这篇文章主要介绍了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 观察者模式的资料请关注脚本之家其它相关文章!

相关文章

  • Spring session 获取当前账户登录数的实例代码

    Spring session 获取当前账户登录数的实例代码

    这篇文章主要介绍了Spring session 获取当前账户登录数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • maven依赖关系中的<scope>provided</scope>使用详解

    maven依赖关系中的<scope>provided</scope>使用详解

    这篇文章主要介绍了maven依赖关系中的<scope>provided</scope>使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java RabbitMQ 中的消息长期不消费会过期吗

    Java RabbitMQ 中的消息长期不消费会过期吗

    RabbitMQ支持消息的过期时间,在消息发送时可以进行指定。 RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过了队列的超时时间配置,那么消息会自动的清除
    2021-09-09
  • SpringBoot集成SFTP客户端实现文件上传下载实例

    SpringBoot集成SFTP客户端实现文件上传下载实例

    这篇文章主要为大家介绍了SpringBoot集成SFTP客户端实现文件上传下载实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Java实现PNG图片格式转BMP图片格式

    Java实现PNG图片格式转BMP图片格式

    在实际开发中,有时需要在不同平台、不同应用场景中对图片格式进行转换,本文主要介绍了如何使用 Java 语言实现将 PNG 格式的图片转换为 BMP 格式的图片,需要的可以了解下
    2025-03-03
  • java中RabbitMQ高级应用

    java中RabbitMQ高级应用

    本文主要介绍了java中RabbitMQ高级应用,中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • java对接微信支付之JSAPI支付(微信公众号支付)

    java对接微信支付之JSAPI支付(微信公众号支付)

    这篇文章主要给大家介绍了关于java对接微信支付之JSAPI支付(微信公众号支付)的相关资料,微信JSAPI支付是近年来非常流行的一种支付方式,它使用了微信支付的SDK和demo来实现支付接口的对接,需要的朋友可以参考下
    2023-07-07
  • java实现高效的枚举元素集合示例

    java实现高效的枚举元素集合示例

    Set是Java集合类的重要组成部分,它用来存储不能重复的对象。枚举类型也要求其枚举元素各不相同。看起来枚举类型和集合是很相似的。然而枚举类型中的元素不能随意的增加、删除,作为集合而言,枚举类型非常不实用。EnumSet是专门为enum实现的集合类,本实例将演示其用法
    2014-03-03
  • Java ConcurrentHashMap的使用示例

    Java ConcurrentHashMap的使用示例

    这篇文章主要介绍了Java ConcurrentHashMap的使用示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-04-04
  • java 中归并排序算法详解

    java 中归并排序算法详解

    这篇文章主要介绍了java 中归并排序算法详解的相关资料,归并排序算法又称为合并排序算法,是一种时间复杂度为O(N logN)的排序算法,因而其在平常生活工作中应用非常广泛,需要的朋友可以参考下
    2017-09-09

最新评论