笨蛋学设计模式行为型模式-观察者模式【14】

8.1观察者模式⬆️⬆️⬆️

8.1.1概念

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

8.1.2场景

​ 在我们生活中,用户可以在音乐播放平台关注多个歌手,而当有歌手发布新的歌曲时,可以将歌曲发布到音乐播放平台,而平台会将新的歌曲详细信息发送给关注该歌手的用户。而此时歌手就相当于是观察者模式的主题对象,每个关注的用户则是观察者模式中的观察者对象,通过该模式,用户可以很及时的听到歌手的新歌曲,而歌手也可以很轻松的通知用户新歌曲的发布。

8.1.3优势 / 劣势

  • 灵活性:提供了灵活的观察者注册机制,可以随时添加或删除观察者,使得系统更加灵活和可扩展
  • 自动更新:当被观察者的状态发生改变时,所有依赖它的观察者都会自动收到通知并更新,提高了系统的自动化程度

  • 性能影响:当被观察者的状态发生改变时,所有观察者都会收到通知并且进行相应的通知,可能导致大量的通知和计算,影响系统性能
  • 通知竞态条件:若多个线程同时修改被观察者的状态,可能会产生竞态条件,导致某些观察者未能及时收到通知或收到错误的通知

8.1.4观察者模式可分为

  • 主题Subject:就是被观察的对象,可以维护一组观察者,当主题本身发生改变时就会通知观察者
  • 观察者Observer:观察主题的对象,当"被观察"的主题发生变化时,观察者就会得到通知并执行相应的处理

观察者的基本结构:
  • 主题Subject:一般会定义成一个接口,提供方法用于注册、删除、通知观察者,通常也包含一个状态,当状态发生改变时,通知所有的观察者
  • 观察者Observer:观察者也需要实现一个接口,包含一个更新方法,在接收主题通知时执行对应的操作
  • 具体主题ConcreteSubject:主题的具体实现,维护一个观察者列表,包含了观察者的注册、删除、通知方法
  • 具体观察者ConcreteObserver:观察者接口的具体实现,每个具体

8.1.5观察者模式

package com.technologystatck.designpattern.mode.observer;

import java.util.ArrayList;
import java.util.List;

public class Observers {
   
    public static void main(String[] args) {
   

        //创建具体主题对象
        ConcreteSubject concreteSubject = new ConcreteSubject();

        //创建具体观察者对象
        Observer concreteObserverA = new ConcreteObserver();
        Observer concreteObserverB = new ConcreteObserver();

        //注册观察者
        concreteSubject.registerObserver(concreteObserverA);
        concreteSubject.registerObserver(concreteObserverB);

        //调用主题方法
        concreteSubject.setState("有新的观察者注册");
    }
}

//主题接口(主题)
interface Subject{
   
    //注册观察者
    void registerObserver(Observer observer);

    //移除观察者
    void removeObserver(Observer observer);

    //通知观察者
    void notifyObserver();
}

//观察者接口(观察者)
interface Observer{
   
    //更新方法
    void update(String message);
}

//具体主题实现
class ConcreteSubject implements Subject{
   

    //观察者列表
    private List<Observer> observers = new ArrayList<>();

    //状态
    private String state;

    //注册观察者方法(注册)
    @Override
    public void registerObserver(Observer observer) {
   
        observers.add(observer);
    }

    //移除观察者方法(移除)
    @Override
    public void removeObserver(Observer observer) {
   
        observers.remove(observer);
    }

    //通知观察者方法(通知)
    //遍历观察者列表,并通知每个观察者更新状态
    @Override
    public void notifyObserver() {
   
        for (Observer observer : observers) {
   
            observer.update(state);
        }
    }

    //更新状态
    public void setState(String state) {
   
        this.state = state;
        notifyObserver();
    }
}
//具体观察者实现
class ConcreteObserver implements Observer{
   
    //更新方法
    @Override
    public void update(String message) {
   
        System.out.println(message);
    }
}



8.1.6实战

8.1.6.1题目描述

小明所在的学校有一个时钟(主题),每到整点时,它就会通知所有的学生(观察者)当前的时间,请你使用观察者模式实现这个时钟通知系统。

注意点:时间从 0 开始,并每隔一个小时更新一次。

8.1.6.2输入描述

输入的第一行是一个整数 N(1 ≤ N ≤ 20),表示学生的数量。

接下来的 N 行,每行包含一个字符串,表示学生的姓名。

最后一行是一个整数,表示时钟更新的次数。

8.1.6.3输出描述

对于每一次时钟更新,输出每个学生的姓名和当前的时间。

8.1.6.4代码
package com.technologystatck.designpattern.mode.observer;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Test {
   
    public static void main(String[] args) {
   
        Scanner scanner = new Scanner(System.in);
        // 读取学⽣数量
        int N = scanner.nextInt();
        // 创建时钟
        Clock clock = new Clock();
        // 注册学⽣观察者
        for (int i = 0; i < N; i++) {
   
            String studentName = scanner.next();
            clock.registerObserver(new Student(studentName));
        }
        // 读取时钟更新次数
        int updates = scanner.nextInt();
        // 模拟时钟每隔⼀个⼩时更新⼀次
        for (int i = 0; i < updates; i++) {
   
            clock.tick();
        }
    }
}

// 观察者接⼝
interface Observer {
   
    void update(int hour);
}
// 主题接⼝
interface Subject {
   
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
// 具体主题实现
class Clock implements Subject {
   
    private List<Observer> observers = new ArrayList<>();
    private int hour = 0;
    @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(hour);
        }
    }
    public void tick() {
   
        hour = (hour + 1) % 24; // 模拟时间的推移
        notifyObservers();
    }
}
// 具体观察者实现
class Student implements Observer {
   
    private String name;
    public Student(String name) {
   
        this.name = name;
    }
    @Override
    public void update(int hour) {
   
        System.out.println(name + " " + hour);
    }
}


8.1.7总结

  • 优点:可以灵活的增加 / 删除观察者对象,而不影响其他相关对象的功能
  • 总结:定义一对多的依赖关系,让多个观察者对象同时监听某一主题对象的状态变化,实现自动更新
  • 场景:适用于一个对象的状态变化会影响到其他对象,并且希望这些对象在状态变化时能够自动更新的情况

相关推荐

  1. 笨蛋设计模式行为模式-观察模式14

    2024-01-20 21:36:04       49 阅读
  2. 笨蛋设计模式行为模式-策略模式16

    2024-01-20 21:36:04       48 阅读
  3. 笨蛋设计模式行为模式-命令模式19

    2024-01-20 21:36:04       46 阅读
  4. 笨蛋设计模式行为模式-访问模式【21】

    2024-01-20 21:36:04       48 阅读
  5. 笨蛋设计模式行为模式-中介模式【24】

    2024-01-20 21:36:04       54 阅读
  6. 笨蛋设计模式行为模式-状态模式【20】

    2024-01-20 21:36:04       60 阅读
  7. 笨蛋设计模式行为模式-备忘录模式【22】

    2024-01-20 21:36:04       48 阅读
  8. 笨蛋设计模式行为模式-责任链模式18

    2024-01-20 21:36:04       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-20 21:36:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-20 21:36:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-20 21:36:04       82 阅读
  4. Python语言-面向对象

    2024-01-20 21:36:04       91 阅读

热门阅读

  1. 基本算法--分治法(快排,归并)习题

    2024-01-20 21:36:04       62 阅读
  2. 鸿蒙harmony--HTTP数据请求的简单使用

    2024-01-20 21:36:04       56 阅读
  3. 微信小程序实现下拉简单展示接口数据

    2024-01-20 21:36:04       57 阅读
  4. 嵌入式C语言--LD文件的概念

    2024-01-20 21:36:04       60 阅读
  5. Jtti:Ubuntu中如何搭建LAMP开发环境

    2024-01-20 21:36:04       53 阅读
  6. 《python算法与数据结构2000讲》0217. 存在重复元素

    2024-01-20 21:36:04       60 阅读
  7. 计算机网络(第六版)复习提纲5

    2024-01-20 21:36:04       56 阅读