Java中常用的设计模式之观察者模式详解

目录
  • 优点
  • 缺点
  • 使用场景
  • 注意事项
  • 一、实现方式
    • 1、观察者抽象类
    • 2、第一个观察者
    • 3、第二个观察者
    • 4、第三个观察者
    • 5、定义主题
  • 二、测试
  • 总结

优点

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

2.建立一套触发机制。

缺点

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

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

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

使用场景

一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。

一个对象必须通知其他对象,而并不知道这些对象是谁。

需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项

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

2.避免循环引用。

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

一、实现方式

1、观察者抽象类

package com.asurplus.common.observe;
/**
 * 观察者
 */
public abstract class Observer {
    protected Subject subject;
    /**
     * 发布事件
     */
    public abstract void update();
}

2、第一个观察者

package com.asurplus.common.observe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Observer1 extends Observer {
    public Observer1(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }
    @Override
    public void update() {
        log.info("观察者 1 收到通知:{}", this.subject.getState());
    }
}

3、第二个观察者

package com.asurplus.common.observe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Observer2 extends Observer {
    public Observer2(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }
    @Override
    public void update() {
        log.info("观察者 2 收到通知:{}", this.subject.getState());
    }
}

4、第三个观察者

package com.asurplus.common.observe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Observer3 extends Observer {
    public Observer3(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }
    @Override
    public void update() {
        log.info("观察者 3 收到通知:{}", this.subject.getState());
    }
}

5、定义主题

package com.asurplus.common.observe;
import java.util.ArrayList;
import java.util.List;
/**
 * 主题
 */
public class Subject {
    /**
     * 观察者列表
     */
    private List<Observer> observers = new ArrayList<>();
    /**
     * 标志
     */
    private int state;
    public int getState() {
        return state;
    }
    /**
     * 标识被改变
     *
     * @param state
     */
    public void setState(int state) {
        this.state = state;
        // 通知所有观察者
        notifyAllObservers();
    }
    /**
     * 添加进接收者列表
     *
     * @param observer
     */
    public void attach(Observer observer) {
        observers.add(observer);
    }
    /**
     * 通知所有人被改变
     */
    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

类似于消息发布一样,有多个接收者,当标志位被改变的时候,通知多个接收者。

二、测试

package com.asurplus.common.observe;
public class TestMain {
    public static void main(String[] args) {
        // 创建主题
        Subject subject = new Subject();
        // 添加观察者
        new Observer1(subject);
        new Observer2(subject);
        new Observer3(subject);
        // 改变标志
        subject.setState(10);
    }
}

输出结果

可以看出,三个接收者都收到了事件通知,从而实现了我们的观察者模式。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java设计模式之java观察者模式详解

    目录 引言 介绍 角色 原理类图 微信订阅号的案例 总结 优点 缺点 适用场景 观察者模式的典型应用 JDK 提供的观察者接口 Guava EventBus 中的观察者模式 Spring ApplicationContext 事件机制中的观察者模式 参考文章 总结 引言 观察者模式是设计模式中的 "超级模式",其应用随处可见,我们以微信公众号为例. 微信公众号有服务号.订阅号和企业号之分.当我们在公众号上发布一篇博文推送时,订阅的用户都能够在我发布推送之后及时接收到推送,即可方便地在手

  • Java通俗易懂系列设计模式之观察者模式

    介绍 观察者模式是行为设计模式之一.当您对对象的状态感兴趣并希望在有任何更改时收到通知时,观察者设计模式非常有用.在观察者模式中,监视另一个对象状态的对象称为Observer,正在被监视的对象称为Subject. 根据GoF,观察者设计模式的意图是; 定义对象之间的一对多依赖关系,以便当一个对象更改状态时,将自动通知和更新其所有依赖项. Subject包含一个观察者列表,用于通知其状态的任何变化,因此它应该提供观察者可以注册和注销自己的方法.Subject还包含一种方法,用于通知所有观察者任何更

  • Java设计模式之观察者模式(Observer模式)

    一.观察者模式是什么? 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).当一个对象被修改时,则会自动通知依赖它的对象.观察者模式属于行为型模式. 人话: 就像微信公众号推送消息,订阅的人能收到,没订阅的收不到,还可以取消/添加订阅 二.模式分析 2.1 四个角色 抽象主题(抽象被观察者角色):也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者.抽象主题提供一个接口,可以增加和删除观察者角色.一般用一个抽象类和接口来实现

  • 深入理解Java设计模式之观察者模式

    目录 一.什么是观察者模式 二.观察者模式的结构 三.观察者模式的使用场景 使用观察者模式也有两个重点问题要解决: 广播链的问题. 异步处理问题. 四.观察者模式的优缺点 五.观察者模式的实现 六.观察者模式和委托的结合 七.总结 一.什么是观察者模式 在许多设计中,经常涉及多个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象中的数据变化,也就是说当对象间存在一对多关系时,在这样的情况下就可以使用观察者模式.当一个对象被修改时,则会自动通知它的依赖对象. 观察者模式是

  • Java中常用的设计模式之观察者模式详解

    目录 优点 缺点 使用场景 注意事项 一.实现方式 1.观察者抽象类 2.第一个观察者 3.第二个观察者 4.第三个观察者 5.定义主题 二.测试 总结 优点 1.观察者和被观察者是抽象耦合的. 2.建立一套触发机制. 缺点 1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间. 2.如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃. 3.观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而

  • Java中常用的设计模式之单例模式详解

    目录 注意 优点 缺点 使用场景 一.实现方式 二.实现方式 三.测试 总结 注意 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 优点 1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存). 2.避免对资源的多重占用(比如写文件操作). 缺点 1.没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化. 使用场景 1.要求生产唯一序列号. 2.WE

  • Java中常用的日期类图文详解

    目录 前言 Date 为什么Date的大部分方法被弃用 注释 翻译 目前可用方法的测试示例 可用方法 示例 Date小结 Calendar 简单介绍 常用的方法 获取实例 获取日期里的信息 日期的加减与滚动 日期的设置 测试实例代码 DateFormat与SimpleDateFormat DateFormat 常用方法 测试实例 SimpleDateFormat 主要方法 测试示例 编写一个简单的日期工具类 工具类 测试示例 总结 前言 本文将分析Java中的Date.Calendar.Date

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

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

  • java中Executor,ExecutorService,ThreadPoolExecutor详解

    java中Executor,ExecutorService,ThreadPoolExecutor详解 1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thre

  • Java中Properties类的操作实例详解

    Java中Properties类的操作实例详解 知识学而不用,就等于没用,到真正用到的时候还得重新再学.最近在看几款开源模拟器的源码,里面涉及到了很多关于Properties类的引用,由于Java已经好久没用了,而这些模拟器大多用Java来写,外加一些脚本语言Python,Perl之类的,不得已,又得重新拾起.本文通过看<Java编程思想>和一些网友的博客总结而来,只为简单介绍Properties类的相关操作.  一.Java Properties类 Java中有个比较重要的类Properti

  • Java动态代理(设计模式)代码详解

    基础:需要具备面向对象设计思想,多态的思想,反射的思想: Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对Java动态代理机制有更加深入的理解.本文首先从Java动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理模

  • Java中接口和抽象类的区别详解

    需求:接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承实体类(concrete class)?抽象类中是否可以有静态的main方法? 先说明二者的定义,然后聊聊需求,最后分析二者的区别. 含有abstract修饰符的类即为抽象类,抽象类不能创建实例对象.含有抽象方法的类必须定义为abstract class.在abstract class中,方法不必是抽象的,但是抽象方法必须在具体子类中实现,所以,不能有抽象构造方法或抽象静态方法.子类如果没有实现抽象父类中的所

  • SpringMVC中常用注解与使用方法详解

    MVC简介 MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写, 是一种用于设计创建 Web 应用程序表现层的模式. Model(模型): 通常指的就是我们的数据模型.作用一般情况下用于封装数据. View(视图): 通常指的就是我们的 jsp 或者 html.作用一般就是展示数据的. 通常视图是依据模型数据创建的. Controller(控制器): 是应用程序中处理用户交互的部分.作用一般就是处理程序逻辑的.

  • Java 中泛型 T 和 ? 的区别详解

    目录 泛型中 T 类型变量 和 ? 通配符 区别 Generic Types 类型变量 用法 2.声明通用的方法 – 泛型方法: 有界类型参数 Wildcards 通配符 1.上界通配符:? extend 上界类型 2.无界通配符:? 3.下界通配符:? super 子类 类型擦除 泛型中 T 类型变量 和 ? 通配符 区别 定义不同 :T 是类型变量,? 是通配符 使用范围不同: ? 通配符用作 参数类型.字段类型.局部变量类型,有时作为返回类型(但请避免这样做) T 用作 声明类的类型参数.

随机推荐