观察者模式学习笔记(java版)
场景引入
如图,为广播机制,只需要一个人讲话,所有的收音机都能接收到。把播音员看做目标对象,收音机看成观察者,目标对象的状态改变的时候,观察者可以得知目标对象的状态并作出反应。
核心
- 观察者模式主要用于:1、当一个对象(目标对象)的状态变化时,他需要及时告知一系列对象(观察者者对象),令他们做出响应。
- 通知观察者的方式:
- 推:每次都会把通知以广播的方式发送给所有观察者,所有观察者只能被动接收
- 拉:观察者只需要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。
实现
1.手动实现
package com.qianyu.gof.factory.observer;
import java.util.ArrayList;
import java.util.List;
/**
* @author lijing
* @date 2019-04-09-16:59
* @discroption 目标对象的基类
*/
public class Subject {
protected List<Observer> list=new ArrayList<Observer>();
public boolean registerObserver(Observer obs){
return list.add(obs);
}
public boolean removeObserver(Observer obs){
return list.remove(obs);
}
public void notifyAllObservers(){
for (Observer obs : list) {
obs.update(this);
}
}
}
package com.qianyu.gof.factory.observer;
/**
* @author lijing
* @date 2019-04-09-17:04
* @discroption 目标对象
*/
public class ConcreteSubject extends Subject{
//目标对象的状态
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
//目标对象状态发生变化,需要通知所有观察者
this.notifyAllObservers();
}
}
package com.qianyu.gof.factory.observer;
/**
* @author lijing
* @date 2019-04-09-16:58
* @discroption 观察者接口
*/
public interface Observer {
public void update(Subject sub);
}
package com.qianyu.gof.factory.observer;
/**
* @author lijing
* @date 2019-04-09-17:02
* @discroption 观察者A
*/
public class ObserverA implements Observer{
//观察者的状态要与目标对象的状态一致
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
@Override
public void update(Subject sub) {
this.status=((ConcreteSubject)sub).getStatus();
}
}
测试类:
package com.qianyu.gof.factory.observer;
/**
* @author lijing
* @date 2019-04-09-17:06
* @discroption 观察者对象测试类
*/
public class ObserverTest {
public static void main(String[] args) {
//目标对象
ConcreteSubject cs = new ConcreteSubject();
//观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA();
//注册观察者
cs.registerObserver(o1);
cs.registerObserver(o2);
cs.registerObserver(o3);
//修改目标对象的状态
cs.setStatus(500);
//打印观察者的状态
System.out.println(o1.getStatus());
System.out.println(o2.getStatus());
System.out.println(o3.getStatus());
//再次修改目标对象的状态
cs.setStatus(200);
//再次打印观察者的状态
System.out.println(o1.getStatus());
System.out.println(o2.getStatus());
System.out.println(o3.getStatus());
}
}
测试结果:
UML类图:
2.借助javaSE中的java.util.Observable和java.util.Observer来实现
package com.qianyu.gof.factory.factory2;
import java.util.Observable;
/**
* @author lijing
* @date 2019-04-09-19:53
* @discroption 目标对象
*/
public class ConcreteSubject extends Observable {
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status) {
//目标对象状态发生了改变
this.status = status;
//表示目标对象做出了更改
setChanged();
//通知所有观察者
notifyObservers();
}
}
package com.qianyu.gof.factory.factory2;
import java.util.Observable;
import java.util.Observer;
/**
* @author lijing
* @date 2019-04-09-19:52
* @discroption 观察者A
*/
public class ObserverA implements Observer {
private int status;
@Override
public void update(Observable o, Object arg) {
this.status = ((ConcreteSubject)o).getStatus();
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
package com.qianyu.gof.factory.factory2;
/**
* @author lijing
* @date 2019-04-09-20:01
* @discroption 观察者模式测试类
*/
public class ObserverTest {
public static void main(String[] args) {
//目标对象
ConcreteSubject cs = new ConcreteSubject();
//观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA();
//将上面三个观察者对象添加到目标对象subject的观察者容器中
cs.addObserver(o1);
cs.addObserver(o2);
cs.addObserver(o3);
//修改目标对象的状态
cs.setStatus(500);
System.out.println(o1.getStatus());
System.out.println(o2.getStatus());
System.out.println(o3.getStatus());
//再次修改目标对象的状态
cs.setStatus(200);
System.out.println(o1.getStatus());
System.out.println(o2.getStatus());
System.out.println(o3.getStatus());
}
}
测试结果:
UML类图:
开发中常见的场景:
- 聊天室程序的,服务器转发给所有客户端
- 网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发
- 邮件订阅
- Servlet中,监听器的实现
- Android中,广播机制
- JDK的AWT中事件处理模型,基于观察者模式的委派事件模型(Delegation Event Model)
– 事件源----------------目标对象
– 事件监听器------------观察者 - 京东商城中,群发某商品打折信息
——基于高淇老师的《java300集》