观察者模式Observer
用于1:N的通知,当一个对象(目标对象Subject或Observable)状态发生改变时,他需要通知一系列对象(观察者对象Observer)使他们做出响应。
通知观察者的方式:
推:每次会把广播以通知的方式发生给所有观察者,观察者只能被动接收。
拉:观察者可以自主决定什么时候接收通知
1.场景
玩CSGO时,当一个玩家的位置发生改变时,服务器会把改变后的位置数据发送给每个玩家。
CSDN中,一些人订阅了java的模块,当有这个模块的内容发布时,就会将这些内容发给所有订阅的人。
这些场景我们都可以使用观察者模式处理。我们把多个玩家,订阅者称为观察者,需要同步给多个订阅者的数据封装到对象中,称为目标。
2.实现推方式
2.1手写
package com.liang.observer;
public interface Observer {
void updata(Subject s);
}
package com.liang.observer;
import java.util.ArrayList;
import java.util.List;
/**
* @author Administrator
*
*/
public abstract class Subject {
protected List<Observer> list=new ArrayList<>();
public void order(Observer o) {
list.add(o);
}
public void remove(Observer o) {
list.remove(o);
}
public void notifyAllObserver() {
for (Observer obs : list) {
obs.updata(this);
}
}
}
package com.liang.observer;
/**
* @author Administrator
*
*/
public class ConcreteSubject extends Subject {
private String orderData;
public String getOrderData() {
return orderData;
}
public void setOrderData(String orderData) {
this.orderData = orderData;
this.notifyAllObserver();
}
}
package com.liang.observer;
/**
* @author Administrator
*
*/
public class ConcreteObserver implements Observer {
String data;
@Override
public void updata(Subject s) {
// TODO 自动生成的方法存根
data=((ConcreteSubject)s).getOrderData();
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
package com.liang.observer;
/**
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
ConcreteSubject cs=new ConcreteSubject();
ConcreteObserver o1=new ConcreteObserver();
ConcreteObserver o2=new ConcreteObserver();
ConcreteObserver o3=new ConcreteObserver();
cs.order(o3);
cs.order(o2);
cs.order(o1);
cs.setOrderData("观察者模式");
System.out.println(o1.getData());
System.out.println(o2.getData());
System.out.println(o3.getData());
}
}
2.2使用jdk自带的Observer,Observable实现
package com.liang.observer2;
import java.util.Observable;
/**
* @author Administrator
*
*/
public class ConcreteSubject extends Observable {
private String date;
public void setDate(String date) {
this.date=date;//目标对象状态发生改变
setChanged();//目标对象状态已经改变
notifyObservers(date);//通知所有观察者
}
public String getDate() {
return date;
}
}
package com.liang.observer2;
import java.util.Observable;
import java.util.Observer;
public class ConcreteObserver implements Observer {
private String myDate;
@Override
public void update(Observable o, Object arg) {
// TODO 自动生成的方法存根
myDate=((ConcreteSubject)o).getDate();
}
public String getMyDate() {
return myDate;
}
public void setMyDate(String myDate) {
this.myDate = myDate;
}
}
package com.liang.observer2;
/**
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
ConcreteSubject cs=new ConcreteSubject();//目标
ConcreteObserver co1=new ConcreteObserver();//观察者
ConcreteObserver co2=new ConcreteObserver();//观察者
ConcreteObserver co3=new ConcreteObserver();//观察者
//设置目标广播的对象
cs.addObserver(co3);
cs.addObserver(co2);
cs.addObserver(co1);
cs.setDate("java大数据");//改变目标状态
System.out.println(co1.getMyDate());
System.out.println(co2.getMyDate());
System.out.println(co3.getMyDate());
}
}