设计模式之观察者模式

定义:对象间的一种一对多的依赖关系,当一个对象的状态发货所能改变时,所有依赖它的对象都得到通知并被自动更新。

例子:报纸-邮局-用户

不用设计模式实现

被观察者

java 复制代码
package com.tao.YanMoDesignPattern.observer.case3_Origin;



import java.util.Observable;

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description Java本身带有的观察者
 * @Version 1.0
 **/
public class NewsPaper extends Observable {

    // 具体的报纸内容
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
        // 内容有了,说明出报纸了,那就通知所有的读者(观察者)
        // 注意在这里用Java 的Observer 模式的时候,下面这句话不可少
        this.setChanged();
        // 主动通知,这里用的是推的方式
        this.notifyObservers(this.content);
        // 如果用拉的方式
//        this.notifyObservers();
    }
}

观察者

java 复制代码
package com.tao.YanMoDesignPattern.observer.case3_Origin;

import com.tao.YanMoDesignPattern.observer.pattern.Subject;

import java.util.Observable;
import java.util.Observer;

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description
 * @Version 1.0
 **/
public class Reader implements Observer {

    public String getName() {
        return name;
    }

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

    // 读者的姓名
    private String name;

    @Override
    public void update(Observable o, Object arg) {
        // 推
        System.out.println(name +"收到报纸了,阅读先.目标过来的内容是:"+ arg);

        // 拉
        System.out.println(name +"收到报纸了,阅读先.主动拉倒的内容是 :"+((NewsPaper)o).getContent());
    }
}

测试

java 复制代码
package com.tao.YanMoDesignPattern.observer.case3_Origin;


/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description 使用观察者模式
 * @Version 1.0
 **/
public class Client {

    public static void main(String[] args) {
        // 创建一个报纸,作为被观察者
        NewsPaper subject = new NewsPaper();
        // 创建阅读者 ,也就是观察者
        Reader reader = new Reader();
        reader.setName("涛");

        Reader reader1 = new Reader();
        reader1.setName("张三");
        Reader reader2 = new Reader();
        reader2.setName("Li");

        // 注册阅读者
        subject.addObserver(reader1);
        subject.addObserver(reader2);
        subject.addObserver(reader);

        subject.setContent("现在使用的是Java自带的Oberver Observable 实现观察者模式!!");
    }
}

标准的观察者模式

java 复制代码
package com.tao.YanMoDesignPattern.observer.pattern;

public interface Observer {

    // 更新接口
    public void update(Subject subject);

}
java 复制代码
package com.tao.YanMoDesignPattern.observer.pattern;

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

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description
 * @Version 1.0
 **/
public class Subject {

    // 用来保存注册的观察者对象
    private List<Observer> observers = new ArrayList<>();

    /**
     * 注册观察者对象
     * @param observer
     */
    public void attach(Observer observer){
        observers.add(observer);
    }

    public void detach(Observer observer){
        observers.remove(observer);
    }

    /**
     * 通知所有的观察者
     */
    protected void notifyObservers(){
        for (Observer observer : observers) {
            observer.update(this);
        }
    }
}
java 复制代码
package com.tao.YanMoDesignPattern.observer.pattern;


/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description
 * @Version 1.0
 **/
public class ConcreteObserver implements Observer {

    // 观察者的状态
    private String observerState;

    public void update(Subject subject) {
        // 具体的更新实现
        // 这里可能需要更新观察者的状态,使其与目标的状态保持一致
        observerState = ((ConcreteSubject) subject).getSubjectState();
    }
}
java 复制代码
package com.tao.YanMoDesignPattern.observer.pattern;

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description 具体的目标对象,负责把有关状态存入到相应的观察者对象
 * 并在自己状态改变时,通知各个观察者
 * @Version 1.0
 **/
public class ConcreteSubject extends Subject{

    // 目标对象的状态
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        // 状态发生改变,通知各个观察者
        this.notifyObservers();
    }
}

使用观察者模式实现

被观察者(报纸)

复制代码
package com.tao.YanMoDesignPattern.observer.case1_Newspaper;

import com.tao.YanMoDesignPattern.observer.pattern.Subject;

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description
 * @Version 1.0
 **/
public class NewsPaper extends Subject {

    // 具体的报纸内容
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
        // 内有有了,说明出报纸了,那就通知所有的读者(观察者)
        notifyObservers();
    }
}

观察者(读者)

复制代码
package com.tao.YanMoDesignPattern.observer.case1_Newspaper;

import com.tao.YanMoDesignPattern.observer.pattern.Observer;
import com.tao.YanMoDesignPattern.observer.pattern.Subject;

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description
 * @Version 1.0
 **/
public class Reader implements Observer {

    public String getName() {
        return name;
    }

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

    // 读者的姓名
    private String name;
    @Override
    public void update(Subject subject) {
        System.out.println(name + "收到报纸了,阅读它。内容是: "+((NewsPaper)subject).getContent());
    }


}

测试

复制代码
package com.tao.YanMoDesignPattern.observer.case1_Newspaper;

/**
 * @Author Mi_Tao
 * @Date 2023/7/23
 * @Description 使用观察者模式
 * @Version 1.0
 **/
public class Client {

    public static void main(String[] args) {
        // 创建一个报纸,作为被观察者
        NewsPaper subject = new NewsPaper();
        // 创建阅读者 ,也就是观察者
        Reader reader = new Reader();
        reader.setName("涛");

        Reader reader1 = new Reader();
        reader1.setName("张三");
        Reader reader2 = new Reader();
        reader2.setName("Li");

        // 注册阅读者
        subject.attach(reader1);
        subject.attach(reader2);
        subject.attach(reader);

        subject.setContent("2023-07-23 出新报纸了!!");
    }
}

观察者模式的本质:触发联动

何时使用观察者模式

相关模式

本文参考:《研磨设计模式》

相关代码: https://gitee.com/zitaoyang/design-mode

相关推荐
ApeAssistant3 小时前
Spring + 设计模式 (二十) 行为型 - 中介者模式
spring·设计模式
ApeAssistant3 小时前
Spring + 设计模式 (十九) 行为型 - 访问者模式
spring·设计模式
〆、风神3 小时前
从零实现分布式WebSocket组件:设计模式深度实践指南
分布式·websocket·设计模式
前端大白话4 小时前
Vue2和Vue3语法糖差异大揭秘:一文读懂,开发不纠结!
javascript·vue.js·设计模式
前端大白话4 小时前
JavaScript中`Symbol.for()`和`Symbol()`的区别,在创建全局唯一的`Symbol`值时如何选择使用?
前端·javascript·设计模式
CHQIUU5 小时前
Java 设计模式心法之第25篇 - 中介者 (Mediator) - 用“中央协调”降低对象间耦合度
java·设计模式·中介者模式
Pasregret6 小时前
备忘录模式:实现对象状态撤销与恢复的设计模式
运维·服务器·设计模式
碎梦归途7 小时前
23种设计模式-行为型模式之备忘录模式(Java版本)
java·jvm·设计模式·软考·备忘录模式·软件设计师·行为型模式
东阳马生架构15 小时前
Sentinel源码—8.限流算法和设计模式总结二
算法·设计模式·sentinel
冰茶_17 小时前
C#中常见的设计模式
java·开发语言·microsoft·设计模式·微软·c#·命令模式