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

yizhihongxing

深入解析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日

相关文章

  • 使用RequireJS库加载JavaScript模块的实例教程

    我来详细讲解如何使用RequireJS库加载JavaScript模块。 什么是RequireJS RequireJS是一个JavaScript模块加载器,它可以帮助我们实现依赖模块的异步加载。它采用了AMD规范,并提供了一种便捷的方式,使JavaScript开发人员可以更容易地组织和管理代码。 安装与配置 下载RequireJS 去RequireJS的官方网…

    JavaScript 2023年5月27日
    00
  • 微信小程序开发之改变data中数组或对象的某一属性值

    下面是详细讲解微信小程序开发中改变 data 中数组或对象的某一属性值的完整攻略。 前置知识 在深入讲解如何改变 data 中数组或对象的某一属性值之前,我们需要先了解微信小程序中 data 的用法。在微信小程序中,通过给 Page() 函数传入一个对象,该对象中的 data 属性就是页面的初始数据。 定义 data 对象后,开发者可以通过 this.dat…

    JavaScript 2023年6月10日
    00
  • JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)

    JavaScript字符串对象fromCharCode方法入门实例 简介 fromCharCode()是JavaScript中字符串对象的一个方法,用来将Unicode编码转换成实际字符串。 语法 String.fromCharCode(num1, num2, …, numN) 参数 num1 – 必选参数,当前要被转换的Unicode编码值 (必须在0…

    JavaScript 2023年5月19日
    00
  • JavaScript中property和attribute的区别详细介绍

    JavaScript中property和attribute的区别详细介绍 在JavaScript中,property和attribute指的都是HTML元素的属性,但它们的含义和使用方式有所不同。 property property是HTML元素的属性,是对象的一部分,可以通过JavaScript来操作。在JavaScript中,我们可以使用element.…

    JavaScript 2023年6月10日
    00
  • 学习JavaScript设计模式(接口)

    学习JavaScript设计模式(接口)的完整攻略 什么是接口? 在JavaScript中,接口是一种抽象的概念,用于定义对象应该具有哪些方法。接口只定义方法名和参数,而没有具体的实现。 接口的作用 接口用于规范对象的行为,可以避免代码混乱和不可预测性。它定义了一种契约,约束了对象应该具有哪些方法。使用接口可以使代码更加灵活、可维护和可扩展。 如何定义接口?…

    JavaScript 2023年6月1日
    00
  • JavaScript中子对象访问父对象的方式详解

    下面我来详细讲解“JavaScript中子对象访问父对象的方式详解”。 1. 使用this关键字 在JavaScript中,this关键字表示当前对象。使用this关键字可以访问当前对象的属性和方法,也可以通过this关键字访问当前对象的父对象。假设我们有一个如下的对象,其中包含子对象: let parentObj = { name: "父对象&q…

    JavaScript 2023年5月27日
    00
  • 比较详细的javascript DOM 学习笔记第1/2页

    你好,以下是详细的 “比较详细的JavaScript DOM学习笔记第1/2页” 完整攻略: 目录 DOM介绍 DOM节点操作 DOM样式修改 事件处理 AJAX与DOM 1. DOM介绍 DOM(文档对象模型)是指HTML文档的对象模型。浏览器加载HTML文件后,会生成一颗DOM树。这棵树包含了文档的所有元素,每个节点都是一个对象,开发者可以通过JavaS…

    JavaScript 2023年5月18日
    00
  • Javascript 编码约定(编码规范)

    为了让Javascript代码具备可读性以及易于维护,编写Javascript代码时需要遵循一定的编码约定,也被称为编码规范。接下来,本文将介绍Javascript编码规范的完整攻略。 确定代码的缩进方式 在编写Javascript代码时,我们需要使用缩进来表示不同代码块之间的层次结构,一般约定每个缩进级别使用2或4个空格。其中空格的数量应该保持统一,不要混…

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