一、观察者模式概述
观察者模式主要用于 1 :N 的通知。当一个对象(目标对象 Subject 或 Observable)的状态变化时,它需要通知一系列对象(观察者对象 Observer),令它们做出响应。
通知观察者的方式:
(1)推
每次都会把通知以广播的方式发送给所有观察者,所有观察者只能被动接收。
(2)拉
观察者只要知道有情况即可。至于什么时候获取内容,获取哪些内容,都可以自主决定。
二、观察者模式示例代码
1 /**
2 * 观察者对象接口
3 * @author CL
4 *
5 */
6 public interface Observer {
7 /**
8 * 更新主题
9 * @param subject
10 */
11 void update(Subject subject);
12
13 }
1 /**
2 * 主题对象(目标对象)
3 * @author CL
4 *
5 */
6 public class Subject {
7
8 protected List<Observer> list;
9
10 public Subject() {
11 list = new ArrayList<Observer>();
12 }
13
14 public void addObserver(Observer observer) {
15 list.add(observer);
16 }
17
18 public void removeObserver(Observer observer) {
19 list.remove(observer);
20 }
21
22 /**
23 * 通知所以观察者更新状态
24 */
25 public void notifyAllObserver() {
26 for (Observer o : list) {
27 o.update(this);
28 }
29 }
30
31
32 }
1 /**
2 * 具体的目标对象
3 * @author CL
4 *
5 */
6 public class ConcreteSubject extends Subject {
7
8 /**
9 * 状态
10 */
11 private int state;
12
13 public int getState() {
14 return state;
15 }
16
17 public void setState(int state) {
18 this.state = state;
19 //若主题对象(目标对象)发生的状态发生改变,请通知所有观察者更新状态
20 this.notifyAllObserver();
21 }
22
23 }
1 /**
2 * 观察者
3 * @author CL
4 *
5 */
6 public class ObserverA implements Observer {
7
8 private int myState; //myState需要和目标对象的state保持一致
9
10 @Override
11 public void update(Subject subject) {
12 myState = ((ConcreteSubject) subject).getState();
13 }
14
15 public int getMyState() {
16 return myState;
17 }
18
19 public void setMyState(int myState) {
20 this.myState = myState;
21 }
22
23 }
测试:
1 /**
2 * 测试观察者模式
3 * @author CL
4 *
5 */
6 public class Client {
7
8 public static void main(String[] args) {
9 //目标对象
10 ConcreteSubject sub = new ConcreteSubject();
11
12 //创建三个观察者
13 ObserverA o1 = new ObserverA();
14 ObserverA o2 = new ObserverA();
15 ObserverA o3 = new ObserverA();
16
17 //将这三个观察者添加到目标对象subject的容器中
18 sub.addObserver(o1);
19 sub.addObserver(o2);
20 sub.addObserver(o3);
21
22 //修改目标对象的状态值
23 sub.setState(100);
24
25 System.out.println(o1.getMyState());
26 System.out.println(o2.getMyState());
27 System.out.println(o3.getMyState());
28
29 System.out.println("----------------------");
30
31 //修改目标对象的状态值
32 sub.setState(10);
33
34 System.out.println(o1.getMyState());
35 System.out.println(o2.getMyState());
36 System.out.println(o3.getMyState());
37 }
38 }
控制台输出:
100
100
100
----------------------
10
10
10
三、JDK 中提供类和方法实现观察者模式
1 import java.util.Observable;
2
3 /**
4 * 目标对象
5 * @author CL
6 *
7 */
8 public class ConcreteSubject extends Observable {
9 private int state;
10
11 public int getState() {
12 return state;
13 }
14
15 public void setState(int state) {
16 this.state = state;
17
18 setChanged(); //表示目标对象已经更改状态
19
20 notifyObservers(); //通知所有观察者
21 }
22
23 }
1 import java.util.Observable;
2 import java.util.Observer;
3
4 /**
5 * 观察者对象
6 * @author CL
7 *
8 */
9 public class ObserverA implements Observer {
10
11 private int myState;
12
13 @Override
14 public void update(Observable o, Object arg) {
15 myState = ((ConcreteSubject) o).getState();
16 }
17
18 public int getMyState() {
19 return myState;
20 }
21
22 public void setMyState(int myState) {
23 this.myState = myState;
24 }
25
26 }
测试:
1 /**
2 * 测试利用java.util.*包中的类Observable和接口Obsever实现的观察者模式
3 * @author CL
4 *
5 */
6 public class Client {
7
8 public static void main(String[] args) {
9 //目标对象
10 ConcreteSubject sub = new ConcreteSubject();
11
12 //创建三个观察者
13 ObserverA o1 = new ObserverA();
14 ObserverA o2 = new ObserverA();
15 ObserverA o3 = new ObserverA();
16
17 //将这三个观察者添加到目标对象subject的容器中
18 sub.addObserver(o1);
19 sub.addObserver(o2);
20 sub.addObserver(o3);
21
22 //修改目标对象的状态值
23 sub.setState(666);
24
25 System.out.println(o1.getMyState());
26 System.out.println(o2.getMyState());
27 System.out.println(o3.getMyState());
28
29 System.out.println("----------------------");
30
31 //修改目标对象的状态值
32 sub.setState(123);
33
34 System.out.println(o1.getMyState());
35 System.out.println(o2.getMyState());
36 System.out.println(o3.getMyState());
37 }
38 }
控制台输出:
666
666
666
----------------------
123
123
123
四、观察者模式常见开发应用场景
(1)手机APP中每天的推送广告;
(2)多人联机网络游戏中,服务器实时分发所有玩家的状态;
(3)Servlet 中监听器的实现;
(4)Android 中广播机制;
(5)JDK 的 AWT 事件处理模型,基于观察者模式的委派事件模型(Delegation Event Model)
事件源:目标对象
事件监听器:观察者
(6)…………