定义:对象间的一种一对多的依赖关系,当一个对象的状态发货所能改变时,所有依赖它的对象都得到通知并被自动更新。
例子:报纸-邮局-用户
不用设计模式实现
被观察者
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();}
}
观察者
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;@Overridepublic void update(Observable o, Object arg) {// 推System.out.println(name +"收到报纸了,阅读先.目标过来的内容是:"+ arg);// 拉System.out.println(name +"收到报纸了,阅读先.主动拉倒的内容是 :"+((NewsPaper)o).getContent());}
}
测试
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 实现观察者模式!!");}
}
标准的观察者模式
package com.tao.YanMoDesignPattern.observer.pattern;public interface Observer {// 更新接口public void update(Subject subject);}
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);}}
}
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();}
}
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;@Overridepublic 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