深入解析Java设计模式编程中观察者模式的运用

深入解析Java设计模式编程中观察者模式的运用

观察者模式是一种经典的设计模式,它能够实现对象之间的一对多依赖关系。当一个对象状态发生改变时,其所有关联对象都能够收到通知并自动更新。

观察者模式的定义

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,所有的观察者对象都能够收到通知并自动更新。

观察者模式主要包含以下角色:

  • Subject(主题):它必须能够动态地增加、删除观察者对象;而且当主题状态发生变化时,所有的观察者对象都能够收到通知。
  • ConcreteSubject(具体主题):将有关状态存入到具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发送通知。
  • Observer(观察者):为所有的具体观察者定义一个更新接口,在得到主题通知时更新自己。
  • ConcreteObserver(具体观察者):实现在接收到通知时进行自身状态更新的方法。

观察者模式的应用场景

  • 一个对象的改变会引起其他多个对象的改变,而且这些对象之间存在一种关系可以用被观察者和观察者来描述。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面用观察者模式分离出来,可以分别实现解耦,从而提高系统的灵活性和可维护性。

观察者模式的实现示例

1. 利用观察者模式实现监听器

首先定义主题接口Subject和观察者接口Observer:

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(Object obj);
}

public interface Observer {
    void update(Object obj);
}

然后我们创建一个具体的主题实现类ConcreteSubject,实现Subject接口的相关方法:registerObserver、removeObserver、notifyObservers。

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(Object obj) {
        for (Observer observer : observers) {
            observer.update(obj);
        }
    }
}

最后我们再创建一个具体观察者实现类ConcreteObserver,实现Observer接口的相关方法:update。

public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(Object obj) {
        System.out.println(name + "收到了事件通知,事件内容为:" + obj);
    }
}

下面我们来看一个示例,利用观察者模式实现监听器:

public static void main(String[] args) {
    Subject subject = new ConcreteSubject();
    subject.registerObserver(new ConcreteObserver("观察者1"));
    subject.registerObserver(new ConcreteObserver("观察者2"));

    subject.notifyObservers("事件1发生了");
    subject.notifyObservers("事件2发生了");

    subject.removeObserver(new ConcreteObserver("观察者1"));

    subject.notifyObservers("事件3发生了");
}

输出结果:

观察者1收到了事件通知,事件内容为:事件1发生了
观察者2收到了事件通知,事件内容为:事件1发生了
观察者1收到了事件通知,事件内容为:事件2发生了
观察者2收到了事件通知,事件内容为:事件2发生了
观察者2收到了事件通知,事件内容为:事件3发生了

2. 利用观察者模式实现一比分实时更新的应用

首先定义主题接口Subject和观察者接口Observer:

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

public interface Observer {
    void update(int homeScore, int guestScore);
}

然后我们创建一个具体的主题实现类ConcreteSubject,实现Subject接口的相关方法:registerObserver、removeObserver、notifyObservers。

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int homeScore;
    private int guestScore;

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(homeScore, guestScore);
        }
    }

    public void setScore(int homeScore, int guestScore) {
        this.homeScore = homeScore;
        this.guestScore = guestScore;
        notifyObservers();
    }
}

最后我们再创建一个具体观察者实现类ConcreteObserver,实现Observer接口的相关方法:update。

public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(int homeScore, int guestScore) {
        System.out.println(name + ":主队" + homeScore + " - 客队" + guestScore);
    }
}

下面我们来看一个示例,利用观察者模式实现一比分实时更新的应用:

public static void main(String[] args) throws InterruptedException {
    Subject subject = new ConcreteSubject();
    subject.registerObserver(new ConcreteObserver("用户1"));
    subject.registerObserver(new ConcreteObserver("用户2"));

    for (int i = 0; i < 3; i++) {
        System.out.println("比分更新");
        ((ConcreteSubject) subject).setScore(new Random().nextInt(5), new Random().nextInt(5));
        Thread.sleep(1000);
    }
}

输出结果:

比分更新
用户1:主队3 - 客队1
用户2:主队3 - 客队1
比分更新
用户1:主队1 - 客队1
用户2:主队1 - 客队1
比分更新
用户1:主队2 - 客队3
用户2:主队2 - 客队3

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入解析Java设计模式编程中观察者模式的运用 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • js函数柯里化的方法和作用实例分析

    下面是 JS 函数柯里化的方法和作用实例分析的攻略: 什么是函数柯里化 函数柯里化是一种将接受多个参数的函数转换为接受一个单一参数的函数,并返回一个新的函数的技术。这个新函数能够接着接受剩下的参数,直到接收到所有参数为止。 举个例子,假设有一个 sum 函数可以接受多个数值参数: function sum(a, b, c) { return a + b + …

    JavaScript 2023年5月28日
    00
  • JavaScript浮点数及运算精度调整详解

    JavaScript浮点数及运算精度调整详解 概述 在JavaScript中,使用浮点数进行运算时会出现精度不准确的情况,这是由于JavaScript中的浮点数采用二进制存储,在进行运算时会出现舍入误差的情况。本文将详细讲解浮点数精度问题,以及如何调整浮点数运算的精度来避免误差。 浮点数精度问题 在JavaScript中,浮点数采用IEEE 754标准进行存…

    JavaScript 2023年6月10日
    00
  • 如何编写一个d.ts文件的步骤详解

    当我们使用TypeScript编写JavaScript程序时,我们通常会使用某些第三方库或包。在使用这些库或包时,我们需要引入相应的声明文件,以便TypeScript能够正确地解析该库或包的类型,API和方法等信息。 声明文件一般以.d.ts为扩展名,可以手动编写,也可以使用工具自动生成。以下是编写一个d.ts文件的步骤: 步骤一:创建项目和声明文件 先创建…

    JavaScript 2023年5月27日
    00
  • javascript中动态加载js文件多种解决办法总结

    针对标题“javascript中动态加载js文件多种解决办法总结”,我将详细解释多种解决方法。 方案一:通过DOM API动态创建script标签并插入页面 这是最简单的动态加载js文件的方法。通过javascript的DOM API,创建script标签,设置src属性为对应的js文件路径,最后将该标签插入页面中。 const script = docum…

    JavaScript 2023年5月27日
    00
  • Javascript 异步加载详解(浏览器在javascript的加载方式)

    Javascript 异步加载详解(浏览器在javascript的加载方式) 什么是异步加载 在JavaScript中,异步加载是指浏览器在加载JavaScript文件时,并不会等待文件完全加载完成后再去执行JavaScript文件内的代码。异步加载的好处在于页面不会因为JavaScript加载而被阻塞,同时也可以提高页面的加载速度和性能。 实现异步加载的方…

    JavaScript 2023年5月27日
    00
  • Javascript Date prototype 属性

    JavaScript 中的 Date 对象是一个内置对象,它包含了一些有用的属性和方法,可以用于处理日期和时间。其中,Date.prototype 属性是一个对象,它允许您 Date 对象添加自定义属性和方法。在本教程中,我们将详细介绍 Date.prototype 属性的使用方法。 Date.prototype 属性的基本语法如下: Date.protot…

    JavaScript 2023年5月11日
    00
  • 基于JS实现点击图片在弹出层显示大图效果

    实现点击图片在弹出层显示大图是一种常见的前端页面交互效果,可以提高网站的用户体验度和可用性,下面我将为你讲解实现这个效果的方法和步骤,包括HTML、CSS和JavaScript的代码实现。 首先,在HTML中需要做如下准备: 编写HTML结构,包含要展示的图片和弹出层: “`html “` 在CSS中设置弹出层和其内容的样式: “`css .modal…

    JavaScript 2023年6月11日
    00
  • JS中style属性

    下面是JS中style属性的完整攻略: 1. 简介 在JavaScript中,我们可以使用style属性来修改HTML元素的样式。style属性是一个对象,在该对象中,我们可以使用CSS属性名作为属性名称,将CSS属性值作为属性值,来设置HTML元素的样式属性。 2. 基本用法 style属性在DOM中表示一个元素的样式,可以通过以下方式访问: var el…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部