定义:对象间的一种一对多的依赖关系,当一个对象的状态发货所能改变时,所有依赖它的对象都得到通知并被自动更新。
例子:报纸-邮局-用户
不用设计模式实现
被观察者
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 出新报纸了!!");
}
}
观察者模式的本质:触发联动
何时使用观察者模式
相关模式
本文参考:《研磨设计模式》