Java设计模式之观察者模式

 更新时间:2023年11月30日 10:19:31   作者:啊几  
这篇文章主要介绍了Java设计模式之观察者模式,观察者模式,是一种行为性模型,又叫发布-订阅模式,他定义对象之间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新,需要的朋友可以参考下

什么是观察者模式

  • 先讲什么是行为性模型,行为型模式关注的是系统中对象之间的相互交互,解决系统在运行时对象 之间的相互通信和协作,进一步明确对象的职责。
  • 观察者模式,是一种行为性模型,又叫发布-订阅模式,他定义对象之间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

观察者模式职责

观察者模式主要用于1对N的通知。当一个对象的状态变化时,他需要及时告知一系列对象,令他们做出相应。 实现有两种方式:

  • 推:每次都会把通知以广播的方式发送给所有观察者,所有的观察者只能被动接收。
  • 拉:观察者只要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。

应用实例

现实中有一个金额变化以后,会有短信提示和支付宝提示的例子,短信和支付宝就是金额变化的观察者。

传统模式

金额数据类

public class MoneyData {
    private BigDecimal amount;
    private SMS sms;

    MoneyData(BigDecimal value){
        amount = value;
        sms = new SMS();
    }

    public void increase(BigDecimal value){
        amount = amount.add(value);
        sms.sendMsg("通知:余额+"+value+",现余额为:"+amount);
    }

    public void decrease(BigDecimal value){
        amount = amount.subtract(value);
        sms.sendMsg("通知:余额-"+value+",现余额为:"+amount);
    }
}

短信类

public class SMS {
    public void sendMsg(String str){
        System.out.println("短信"+str);
    }
}

客户端类

public class Client {
    public static void main(String[] args) {

        MoneyData moneyData = new MoneyData(new BigDecimal("5.20"));
        moneyData.increase(new BigDecimal("13.14"));
        moneyData.decrease(new BigDecimal("13.14"));
    }
}

/**
 * 短信通知:余额+13.14,现余额为:18.34
 * 短信通知:余额-13.14,现余额为:5.20
 */

传统模式扩展性十分差,如果新增一个支付宝观察者,需要修改金额数据类,增加一个成员变量。

违反了ocp原则(开闭原则)。可以通过观察者模式修改,让观察者放入一个List列表中

观察者模式

Subject抽象类

public abstract class Subject {

    protected List<Observer> observers = new LinkedList<>();

    public void registerObserver(Observer o) {
        observers.add(o);
    }

    public void removeObserver(Observer o) {
        if(observers.contains(o)){
            observers.remove(o);
        }
    }

    public abstract void notifyObservers(String changeValue);

}

Subject 的具体实现类

public class MoneyData extends Subject{

    private BigDecimal amount;


    MoneyData(BigDecimal value){
        this.amount = value;
    }
    public void increase(BigDecimal value){
        amount = amount.add(value);
        notifyObservers("+"+value);
    }

    public void decrease(BigDecimal value){
        amount = amount.subtract(value);
        notifyObservers("-"+value);
    }
    @Override
    public void notifyObservers(String changeValue) {
        for (Observer observer : observers) {
            observer.sendMsg("通知:余额"+changeValue+",现余额为"+amount);
        }
    }
}

Observer(观察者)接口

public class SMS implements Observer{
    @Override
    public void sendMsg(String msg) {
        System.out.println("短信"+msg);
    }
}

Observer(观察者)的两个具体实现类

public class SMS implements Observer{
    @Override
    public void sendMsg(String msg) {
        System.out.println("短信"+msg);
    }
}
public class Alipay implements Observer{
    @Override
    public void sendMsg(String msg) {
        System.out.println("支付宝"+msg);
    }
}

客户端类

public class Client {
    public static void main(String[] args) {

        MoneyData moneyData = new MoneyData(new BigDecimal("13.14"));
        moneyData.registerObserver(new SMS());
        moneyData.increase(new BigDecimal("52.00"));
        moneyData.decrease(new BigDecimal("52.00"));
        moneyData.registerObserver(new Alipay());
        moneyData.increase(new BigDecimal("5.20"));
        moneyData.decrease(new BigDecimal("5.20"));
    }
}
/**
 * 短信通知:余额+52.00,现余额为65.14
 * 短信通知:余额-52.00,现余额为13.14
 * 短信通知:余额+5.20,现余额为18.34
 * 支付宝通知:余额+5.20,现余额为18.34
 * 短信通知:余额-5.20,现余额为13.14
 * 支付宝通知:余额-5.20,现余额为13.14
 */

应用场景

  • 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

到此这篇关于Java设计模式之观察者模式的文章就介绍到这了,更多相关Java观察者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring cglib 与 jdk 动态代理

    spring cglib 与 jdk 动态代理

    本篇文章主要介绍了spring cglib与jdk动态代理的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-05-05
  • Spring中ApplicationContextAware的使用方法详解

    Spring中ApplicationContextAware的使用方法详解

    ApplicationContextAware 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法,这篇文章主要介绍了Spring中ApplicationContextAware的作用,需要的朋友可以参考下
    2023-03-03
  • SpringBoot多环境配置教程详解

    SpringBoot多环境配置教程详解

    当开发真实的项目时,可能会遇到不同的环境,不同的环境所需要的配置内容也会不尽相同,所以,掌握多环境配置还是非常有必要的。本文为大家准备了SpringBoot多环境配置教程,需要的可以参考下
    2022-06-06
  • java操作PDF文件方法之转换、合成、切分

    java操作PDF文件方法之转换、合成、切分

    最近需要做⼀个把多个pdf报告合并成⼀个以⽅便预览的需求,下面这篇文章主要给大家介绍了关于java操作PDF文件方法之转换、合成、切分的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Maven打jar包的三种方式(小结)

    Maven打jar包的三种方式(小结)

    这篇文章主要介绍了Maven打jar包的三种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • java实现导出数据为zip压缩文件

    java实现导出数据为zip压缩文件

    这篇文章主要为大家详细介绍了java如何实现导出数据为zip压缩文件,并且解压后为json文件,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • Java中的ConcurrentLinkedQueue松散队列解析

    Java中的ConcurrentLinkedQueue松散队列解析

    这篇文章主要介绍了Java中的ConcurrentLinkedQueue松散队列解析,链表是松散的,链表节点并不都是有效的,允许存在无效节点val=null,但是只有最后一个节点才能next=null,需要的朋友可以参考下
    2023-12-12
  • springboot中的多个application文件讲解

    springboot中的多个application文件讲解

    这篇文章主要介绍了springboot中的多个application文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 从基础学java--数组

    从基础学java--数组

    数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们数组的声明创建
    2021-09-09
  • Java轻松实现在Excel中添加超链接功能

    Java轻松实现在Excel中添加超链接功能

    这篇文章主要为大家详细介绍了Java如何轻松实现在Excel中添加超链接功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01

最新评论