前言:
观察者模式可以类比于用户订阅某个频道,比如我订阅了一个短信平台,那么首先我需要在该平台上订阅,此时平台存储关于我的信息,然后平台根据存储的用户信息(可能有多个用户信息)给相关用户发送信息。
订阅
推送消息
目录
一、理论
核心
观察者模式主要用于1:N的通知,当一个对象(目标对象Subject或者Observable)状态变化的时候,他需要及时告知一系列对象(观察者或者Observer)令他们做出反应
通知观察者的方式:
推:
每次都会把通知以广播的方式发送给所有的观察者,所有的观察者只能被动的接受
拉
观察者只要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定
(简单来说就是被订阅者中有一个List属性存储订阅的信息,一旦自身某个属性改变,直接就循环遍历List集合,逐个调用订阅者的Update方法)
二、代码实现
一、类关系图
二、具体实现
- Subject类
package observer;
import java.util.ArrayList;
import java.util.List;
//这就相当于平台
public class Subject {
protected List<Observer> list=new ArrayList<Observer>();
public void registerObserver(Observer observer)
{
list.add(observer);
}
public void removeObserver(Observer observer)
{
list.remove(observer);
}
public void notifyAllObserver()
{
for (Observer observer : list) {
observer.update(this);
}
}
}
- Observer
package observer;
//客户
public interface Observer {
void update(Subject subject);
}
- ObserverA
package observer;
//客户A
public class ObserverA implements Observer {
public int getMyage() {
return myage;
}
public void setMyage(int myage) {
this.myage = myage;
}
private int myage;
@Override
public void update(Subject subject) {
// TODO 自动生成的方法存根
this.myage=((ConcreteSubject)subject).getAge();
System.out.println("我被调用了");
}
}
- ConcreteSubject
package observer;
//具体实现平台
public class ConcreteSubject extends Subject{
protected int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
this.notifyAllObserver();
}
}
调用类
package observer;
public class Client {
public static void main(String[] args) {
ObserverA observerA=new ObserverA();
ObserverA observerA2=new ObserverA();
ObserverA observerA3=new ObserverA();
ConcreteSubject concreteSubject=new ConcreteSubject();
concreteSubject.registerObserver(observerA);
concreteSubject.registerObserver(observerA3);
concreteSubject.registerObserver(observerA2);
concreteSubject.setAge(300);
}
}
实现结果:
二、使用java自带的Observer类实现观察者模式
一、代码实现
package ConcreteObservable;
import java.util.Observable;
//继承了Observable
public class ConcreteObservable extends Observable {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
setChanged();
//标注了我已经改变了,准备通知订阅者
this.notifyObservers(age);//传入参数,我改变了啥
}
}
package ConcreteObservable;
import java.util.Observable;
import java.util.Observer;
public class ObserverA implements Observer {
private int age;
public ObserverA(int age) {
super();
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void update(Observable o, Object arg) {
// TODO 自动生成的方法存根
this.age=((ConcreteObservable)o).getAge();
System.out.println("我被改变了");
}
}
调用:
package ConcreteObservable;
public class Client {
public static void main(String[] args) {
ConcreteObservable concreteObservable=new ConcreteObservable();
ObserverA observerA=new ObserverA(11);
ObserverA observer2=new ObserverA(12);
ObserverA observer3=new ObserverA(13);
concreteObservable.addObserver(observerA);
concreteObservable.addObserver(observer2);
concreteObservable.addObserver(observer3);
concreteObservable.setAge(1000);
System.out.println("===============");
System.out.println(observerA.getAge());
System.out.println(observer2.getAge());
System.out.println(observer3.getAge());
}
}
实现结果:
三、应用场景
聊天室程序,服务器转发给所有的客户端
网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发
邮件订阅
Servlet监听器的实现
Android中广播机制
JDK的AWT事件处理模型是基于观察者模式的委派事件模式
事件源----目标对象
事件监听器--观察者
京东商城中,群发的商品的打折信息