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

相关文章

  • 跟我学习javascript的循环

    跟我学习 JavaScript 的循环 JavaScript 中的循环语句可以让代码块重复执行多次,常用的循环语句有 for 循环、while 循环、do-while 循环等。本攻略将详细讲解 JavaScript 中的循环语句的使用方法。 for 循环 for 循环是最常用的循环语句之一,使用起来非常简便,可以按下面的方式进行: for (let i = …

    JavaScript 2023年5月18日
    00
  • js实现的xml对象转json功能示例

    下面是“JS实现XML对象转JSON功能”的完整攻略: 什么是XML对象和JSON? XML,也就是可扩展标记语言,是一种常用的数据格式,类似于HTML,但是更加灵活,可以自定义标签。我们可以用XML来存储和传输数据。 JSON,也就是JavaScript对象表示法,是一种轻量级的数据交换格式,同时也是JavaScript原生支持的一种数据格式。类似于Jav…

    JavaScript 2023年5月27日
    00
  • 基于Javascript实现返回顶部按钮

    下面是“基于JavaScript实现返回顶部按钮”的完整攻略。 一、先了解什么是返回顶部按钮 返回顶部按钮是指网站页面上的一个链接按钮,当网页向下滚动一定程度时,点击该按钮可以使网页返回顶部。返回顶部按钮可以方便用户快速返回到网页的最顶部,提高用户使用网站的体验度。 二、实现方法 1. 设置html结构和CSS样式 在页面的合适位置增加一个“返回顶部”按钮的…

    JavaScript 2023年6月11日
    00
  • 基于redis的小程序登录实现方法流程分析

    下面我会给出“基于redis的小程序登录实现方法流程分析”的完整攻略。 标题一:前置要求 在开始讲解具体的实现方法前,我们需要先完成以下前置要求: 拥有一个小程序开发者账号并注册小程序。 安装node.js和npm。 安装redis,并且启动redis服务。 标题二:实现步骤 步骤一:安装必要的依赖 我们首先需要安装必要的依赖: npm install ko…

    JavaScript 2023年5月19日
    00
  • JS内置对象和Math对象知识点详解

    JS内置对象和Math对象知识点详解 1. JS内置对象 JavaScript内置对象是指ecmaScript规范定义的对象,这些对象全局可用。JS内置对象不需要额外定义就可以直接使用,并且拥有丰富的API。 1.1. 常见的JS内置对象 以下是一些常见的JS内置对象: String 对象用于处理文本字符串 Number 对象用于处理数字 Object 对象…

    JavaScript 2023年5月28日
    00
  • javascript 数组的定义和数组的长度

    数组是JavaScript中最常用的数据结构之一,可以用来存储多个值。在JavaScript中,数组的定义和长度可以用以下方式来实现: 定义数组 定义一个空数组 javascript let arr = []; 定义一个带有数据的数组 javascript let arr = [1, 2, 3]; 可以通过 Array 构造函数创建数组 javascript…

    JavaScript 2023年5月27日
    00
  • 也说JavaScript中String类的replace函数

    请允许我详细讲解“也说JavaScript中String类的replace函数”的完整攻略。 了解replace函数 首先,我们需要了解一下JavaScript中,String类的replace函数是什么。 replace函数是一个用于替换字符串的工具函数,它的用法如下: str.replace(regexp|substr, newSubStr|functi…

    JavaScript 2023年5月28日
    00
  • js实现缓动动画

    实现缓动动画可以让页面更加生动,让用户更加愉悦地浏览页面。下面是实现缓动动画的完整攻略: 什么是缓动动画? 缓动动画是指物体在经过一段距离时,速度不断变化,而非匀速运动的动画效果。 实现缓动动画的思路 实现缓动动画的思路可以简单归纳如下: 获取要移动元素的初始位置 计算元素需要移动的距离和帧数 计算每一帧的时间间隔和移动距离 在每一帧中更新元素的位置 通过定…

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