观察者设计模式

前言

观察者模式从定义上说就是一种一对多的依赖关系,即当一个对象的状态发生改变时,其它依赖此对象的对象会得到通知并且做出相应的改变。一般有“推”模型和“拉”模型,前者是被观察者将所有信息通知所有人,而后者则是被观察者不主动提供信息,观察者主动索要信息

在这里还是以之前的例子为例

Alt text

这是一个推模型,也就是被观察者根据状态发生改变时将所有信息都主动通知观察者
其中:Jungle(打野)是被观察者,即如果有一些状态变化,如对方打野有动作则将通知observer(目前假定只有上路和adc)
observer:观察者,用来监听被观察者并且根据相应的变化做出变化
top:上单 adc:Adc LesSin:打野盲僧
以下是相关代码:

Jungle(被观察者)

1
2
3
4
5
6
7
8
9
10
public interface Jungle {
//增加观察者
public void addObserve(Observer obs);
//删除观察者
public void deleteObserve(Observer obs);
//通知观察者
public void notifyObserve(String msg);
}

observer(观察者)

1
2
3
4
5
6
public interface Observer {
//收到通知后状态变化
public void notifybyJungle(String msg);
}
}

LeeSin

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
public class LeeSin implements Jungle {
//存放所有的观察者
List<Observer> list=new ArrayList<Observer>();
@Override
public void addObserve(Observer obs) {
list.add(obs);
}
@Override
public void deleteObserve(Observer obs) {
list.remove(obs);
}
@Override
public void notifyObserve(String msg) {
for(Observer obs : list){
obs.notifybyJungle(msg);
}
}
}

top

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class top implements Observer {
//收到消息
public String newmsg;
public String getNewmsg() {
return newmsg;
}
public void setNewmsg(String newmsg) {
this.newmsg = newmsg;
}
@Override
public void notifybyJungle(String msg) {
newmsg=msg;
System.out.println("上单收到:"+newmsg);
}
}

Adc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Adc implements Observer {
public String newmsg;
public String getNewmsg() {
return newmsg;
}
public void setNewmsg(String newmsg) {
this.newmsg = newmsg;
}
@Override
public void notifybyJungle(String msg) {
newmsg=msg;
System.out.println("adc收到:"+newmsg);
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
Jungle jungle=new LeeSin();
Observer obs1=new Adc();
Observer obs2=new top();
jungle.addObserve(obs1);
jungle.addObserve(obs2);
jungle.notifyObserve("敌方打野正在打小龙");
}

下面是输出结果

adc收到:敌方打野正在打小龙
上单收到:敌方打野正在打小龙

如果我们使用拉模型,即观察者主动向被观察者索要信息,那么上面程序将做部分修改

大体思路就是将Jungle(被观察者)的通知函数改为void即

1
2
3
4
5
6
7
8
9
10
public interface Jungle {
//增加观察者
public void addObserve(Observer obs);
//删除观察者
public void deleteObserve(Observer obs);
//通知观察者
public void notifyObserve();
}

相应的observer将更改为
observer(观察者)

1
2
3
4
5
6
public interface Observer {
//收到通知后状态变化
public void notifybyJungle(Jungle jungle);
}
}

对于推与拉模型,如果目标角色过于复杂,则优先使用推模式,反之则使用拉模式

观察者模式应用场景
1、对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变

2、对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节

热评文章