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观察者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JVisualVM之Java性能监控与调优利器详解

    JVisualVM之Java性能监控与调优利器详解

    本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • MyBatis的模糊查询mapper.xml的写法讲解

    MyBatis的模糊查询mapper.xml的写法讲解

    这篇文章主要介绍了MyBatis的模糊查询mapper.xml的写法讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringBoot设置接口超时时间的方法

    SpringBoot设置接口超时时间的方法

    这篇文章主要介绍了SpringBoot设置接口超时时间的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • SpringBoot整合Mybatis LocalDateTime 映射失效的解决

    SpringBoot整合Mybatis LocalDateTime 映射失效的解决

    这篇文章主要介绍了SpringBoot整合Mybatis LocalDateTime 映射失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java数据结构之对象比较详解

    Java数据结构之对象比较详解

    这篇文章主要为大家详细介绍了Java中对象的比较、集合框架中PriorityQueue的比较方式以及PriorityQueue的模拟实现,感兴趣的可以了解一下
    2022-07-07
  • 新手场景Java线程相关问题及解决方案

    新手场景Java线程相关问题及解决方案

    这篇文章主要介绍了新手场景Java线程相关问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Spring @Cacheable 的使用小结

    Spring @Cacheable 的使用小结

    @Cacheable是Spring框架中用于方法级缓存的注解,它主要用于减少方法调用的次数,通过缓存方法的返回结果来提高应用程序的性能,下面就来详细的了解一下
    2026-02-02
  • java实现画图板上画一条直线

    java实现画图板上画一条直线

    这篇文章主要为大家详细介绍了java实现画图板上画一条直线,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • Java EasyExcel实现合并相同内容单元格与动态标题功能

    Java EasyExcel实现合并相同内容单元格与动态标题功能

    这篇文章主要为大家详细介绍了Java EasyExcel如何实现合并相同内容单元格与动态标题功能,文中的示例代码讲解详细,有需要的小伙伴可以参考下
    2023-12-12
  • druid连接池的参数配置示例全面解析

    druid连接池的参数配置示例全面解析

    这篇文章主要为大家介绍了druid连接池的参数配置示例全面解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09

最新评论