您的位置:首页 > 编程语言 > Java开发

设计模式学习笔记---观察者模式Observer pattern(Java版)

2017-02-21 23:12 831 查看


一、场景

网站上,很多人订阅了“NBA主题”新闻,当有这个主题新闻时,就会将这些新闻发给所有订阅的人。(我们可以把多个订阅者、客户称之为观察者;需要同步给多个订阅者的数据封装到对象中,称之为目标。)


二、实质

广播机制 

观察者主要用于1:N的通知。当一个对象(目标对象Subject或Objservable)<消息发布>的状态变化时,他需要及时告知一系列对象(观察者对象Observer)<消息订阅>,令他们做出响应。 

通知观察者的方式: 

推 

–每次都会把通知以广播方式发送给所有观察者,所有观察者只能被动接收。 

拉 

–观察者只要知道有情况即可。至于什么时候获取内容,获取什么内容,都可以自主决定。


三、示例


 
方式一 自己实现
package com.lgd.observer;

public interface Observer {
void update(Subject subject);
}
1
2
3
4
5
6
1
2
3
4
5
6
package com.lgd.observer;

import java.util.ArrayList;
import java.util.List;

public class Subject {
protected List<Observer> list = new ArrayList<Observer>();
public void register(Observer obs){
list.add(obs);
}

public void removeObserver(Observer obs){
list.remove(obs);
}
//通知所有的观察者更新状态
public void notifyAllObservers(){
for(Observer obs:list)
{
obs.update(this);
}
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.lgd.observer;

public class ConcreteSubject extends Subject{
private int state;

public int getState() {
return state;
}

public void setState(int state) {
this.state = state;
//主题对象(目标对象)只发生了变化,请通知所有的观察者。
this.notifyAllObservers();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.lgd.observer;

public class ObserverA implements Observer{
private int myState;//myState需要与目标对象的state保持一致!
@Override
public void update(Subject subject) {
myState = ((ConcreteSubject)subject).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.lgd.observer;

public class Client {
public static void main(String[] args) {
//目标对象
ConcreteSubject subject = new ConcreteSubject();
//创建多个观察者
ObserverA obs1 = new ObserverA();
ObserverA obs2 = new ObserverA();
ObserverA obs3 = new ObserverA();

//将这三个观察者添加到subject对象的观察者队伍中
subject.register(obs1);
subject.register(obs2);
subject.register(obs3);
//修改subject的状态
subject.setState(3000);
System.out.println("========");
//看看观察者的状态是否也发生了变化
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
//修改subject的状态
subject.setState(100);
System.out.println("========");
//看看观察者的状态是否也发生了变化
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

运行结果: 
======== 

3000 

3000 

3000 
======== 

100 

100 

100

方式二 

JavaSE提供了Java.util.Observable和java.util.Observer来实现观察者模式 此方法通知次序会改变
package com.lgd.observer2;

import java.util.Observable;

//目标对象
public class ConcreteSubject extends Observable{
private int state;
public void set(int s){
state = s;//目标对象的状态发生了改变
setChanged();//表示目标对象已经做了更改
notifyObservers(state);//通知所有的观察者
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.lgd.observer2;

import java.util.Observable;
import java.util.Observer;

//观察者
public class ObserverA implements Observer{

private int myState;
@Override
public void update(Observable o, Object arg) {
myState = ((ConcreteSubject)o).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.lgd.observer2;

public class Client {
public static void main(String[] args) {
//创建目标对象Obserable
ConcreteSubject subject = new ConcreteSubject();

//创建观察者
ObserverA obs1 = new ObserverA();
ObserverA obs2 = new ObserverA();
ObserverA obs3 = new ObserverA();

//将上面三个对象添加到目标对象subject的观察者中
subject.addObserver(obs1);
subject.addObserver(obs2);
subject.addObserver(obs3);

//改变subject对象的状态
subject.set(3000);
System.out.println("========");
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
//改变subject对象的状态
subject.set(500);
System.out.println("========");
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

运行结果: 
======== 

3000 

3000 

3000 
======== 

500 

500 

500


四、应用场景

–聊天程序的服务器转发给所有客户端 

–网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发 

–邮件订阅 

–Servlet中,监听器的实现。 

Android中,广播机制 

–JDK的AWT中事件处理模型基于观察者模式的委派事件模型 

事件源–目标对象 

事件监听器–观察者 

–京东商城中,群发某商品打折信息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 设计模式