设计模式之观察者模式

观察者模式概念

它允许一个对象(称为"主题"或"被观察者")在其状态发生变化时通知多个观察者对象,从而实现对象之间的解耦。这种模式常用于实现事件处理机制和发布/订阅模式。

观察者模式的基本概念

Subject(主题)

主题也称为被观察者,负责维护一个观察者列表,并在状态发生变化时通知所有观察者。

Observer(观察者)

观察者负责监听主题的状态变化,并在收到通知时更新自己。

观察者模式的主要组成部分

Subject(主题)

维护一个观察者列表。

提供注册和注销观察者的方法。

提供通知观察者的方法。

Observer(观察者)

定义一个更新的方法,当主题状态发生变化时被调用。

ConcreteSubject(具体主题)

实现Subject接口,维护一个观察者列表,并在状态发生变化时通知所有观察者。

ConcreteObserver(具体观察者)

实现Observer接口,定义具体的更新逻辑。

举个栗子:

老师想通知学生明天老师不上课,老师找到班长把这个消息给班长说了一下,班长接着通知班里的每个学生。

流程

学生进入老师班级==>老师通知班长消息==>班长通知每个学生

4.代码实现

1)Observer观察者类

java 复制代码
package org.xiji.observer2;

/**
 * 订阅者类
 */
public interface Observer {
    /**
     *
     * 接受消息
     */
    void getMessage(Teacher teacher);
}

2)Subject主题类

java 复制代码
package org.xiji.observer2;

/**
 * 发布者类
 */
public interface Subject2 {

    /**
     * 注册
     */
    void register(Student student);

    /**
     * 移除
     */
    void remove(Student student);

    /**
     * 通知
     */
    void notifyStudent();

}

3)Student类

java 复制代码
package org.xiji.observer2;

public class Student implements Observer{
    private String name;

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

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    /**
     * 接受老师的消息
     *
     */

    @Override
    public void getMessage(Teacher teacher) {
        System.out.println(name + "接到通知:" + teacher.getMessage());
    }
}

4)teacher类

java 复制代码
package org.xiji.observer2;

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

/**
 * 教师发布消息
 */
public class Teacher implements Subject2 {
    /**
     * 通知消息
     */
    private String message;
    /**
     * 班级学生集合
     */
    private List<Student> students=new ArrayList<>();

    public Teacher() {
    }

    public Teacher(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    /**
     * 修改订阅信息
     *
     */
    public void setMessage(String message) {
        this.message = message;
        //通知学生
        this.notifyStudent();
    }


    @Override
    public void register(Student student) {
        students.add(student);
        System.out.println("学生:"+student.getName()+"注册成功");
    }

    @Override
    public void remove(Student student) {
        students.remove(student);

    }

    /**
     * 这个方法相当于班长通知学生
     */
    @Override
    public void notifyStudent() {
        /**
         * 通知每个学生
         */
        for (Student student : students) {
            student.getMessage(this);
        }

    }
}

5)观察者测试类

java 复制代码
package org.xiji.observer2;

import java.util.Scanner;

/**
 * 订阅者模式
 */
public class Observer2Main {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();

        Student student1 = new Student("小久");
        Student student2 = new Student("张三");
        Student student3 = new Student("惜己");

        teacher.register(student1);
        teacher.register(student2);
        teacher.register(student3);

        //创建io流
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入通知内容:");
            String message = scanner.nextLine();
            teacher.setMessage(message);

        }


    }
}

6)测试结果

相关推荐
考虑考虑28 分钟前
JDK9中的dropWhile
java·后端·java ee
想躺平的咸鱼干36 分钟前
Volatile解决指令重排和单例模式
java·开发语言·单例模式·线程·并发编程
hqxstudying1 小时前
java依赖注入方法
java·spring·log4j·ioc·依赖
·云扬·1 小时前
【Java源码阅读系列37】深度解读Java BufferedReader 源码
java·开发语言
Bug退退退1232 小时前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq
小皮侠2 小时前
nginx的使用
java·运维·服务器·前端·git·nginx·github
Zz_waiting.2 小时前
Javaweb - 10.4 ServletConfig 和 ServletContext
java·开发语言·前端·servlet·servletconfig·servletcontext·域对象
全栈凯哥2 小时前
02.SpringBoot常用Utils工具类详解
java·spring boot·后端
兮动人3 小时前
获取终端外网IP地址
java·网络·网络协议·tcp/ip·获取终端外网ip地址
呆呆的小鳄鱼3 小时前
cin,cin.get()等异同点[面试题系列]
java·算法·面试