模式简介
模式定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一对象改变状态时,它的所有依赖都会收到通知。
打个比方:一家报社有很多用户,当报社发发布了新的报纸时,这些订阅的读者都能收到。报社就是一的一方,用户就是多的一方。当用户需要订阅报纸,只需要在报社注册即可。
Subject就好比于报社的角色,Obsever就好比于订阅此报社的用户。
为什么使用接口而不是具体类?
为了松耦合。报社不需要知道订阅者具体的信息,他只需要知道你是一个订阅者即可,订阅者信息的改变并不会影响报社的运作,即Subject只会将新的通知发送给实现了Observer接口的类。
JAVA也内置了观察者模式的API,在java.util中的Observer接口和Observable**类**(就是Subject)。在JAVA中讲Subject变成具体的类而不是接口,于是你只能通过继承来实现(JAVA只支持单继承),这大大的降低了其复用的能力以及弹性。毕竟我们需要面向接口编程而不是具体类!因此,我们可以自己实现一个观察者模式的API。
下面我将以球队和球迷作为例子展示。
示例
NBA有三十个队伍,每一个队伍都有各自大量的球迷。
Subject接口:Team
Subject具体实现:HoustonRockets
Observer接口:Fans
Observer具体实现:ChineseFans、USAFans。
public interface Team {
void registerObserver(Fans fans);
void removerObserver(Fans fans);
void notifyAllObserver();
}
public interface Fans {
void wathcMath(String string);
}
public class HoustonRockets implements Team{
//喜欢火箭的球迷
private ArrayList<Fans> fans = new ArrayList<>();
@Override
public void registerObserver(Fans fan) {
fans.add(fan);
}
@Override
public void removerObserver(Fans fan) {
int indexOf = fans.indexOf(fan);
fans.remove(indexOf);
}
//一有比赛就通知所有球迷,但是并不知道球迷来自哪里
@Override
public void notifyAllObserver() {
for (Fans fan : fans) {
fan.wathcMath("Rockets VS BULL!");
}
}
}
//美帝球迷
public class USAFans implements Fans {
// 以备不时之需
private Team team;
public USAFans(Team team) {
this.team = team;
//告诉球队我关注你了!
team.registerObserver(this);
}
@Override
public void wathcMath(String string) {
//表示有比赛就通知我
System.out.println("Fans of Rockets comes from USA! Now we are watching "+string);
}
}
//天朝的球迷
public class ChineseFans implements Fans {
// 以备不时之需
private Team team;
public ChineseFans(Team team) {
this.team = team;
team.registerObserver(this);
}
@Override
public void wathcMath(String string) {
System.out.println("我是来自中国的火箭迷,現在收看:" + string);
}
}
//NBA总的消息平台
public class WatchNBA {
public static void main(String[] args) {
Team team = new HoustonRockets();
//注册球队
Fans chinese = new ChineseFans(team);
Fans usa = new USAFans(team);
//球队有比赛通知大家
team.notifyAllObserver();
}
}
/*我是来自中国的火箭迷,現在收看:Rockets VS BULL!
Fans of Rockets comes from USA! Now we are watching Rockets VS BULL!*/