定义
观察者模式定义了一系列对象之间的一对多的关系,当一个对象改变状态,其他依赖者都会收到通知
简单实现
Subject.java
1
2
3
4
5
6
7
8
9public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers(Object changeData);
}Observer.java
1
2
3
4
5public interface Observer {
public void update(Object ChangeData);
}ConcreteSubject.java
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
28public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int index = observers.indexOf(o);
if (index > 0){
observers.remove(o);
}
}
public void notifyObservers(Object changeData) {
for (Observer o : observers){
o.update(changeData);
}
}
public void change(Object changeData){
notifyObservers(changeData);
}
}ConcreteObserver.java
1
2
3
4
5
6
7
8
9
10
11
12
13public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name){
this.name = name;
}
public void update(Object ChangeData) {
System.out.println("Subject has new data to me " + name +" ChangeData" +ChangeData);
}
}在观察者模式中,每个Subject都会持有观察者的引用,通过调用registerObserver()方法进行注册,通过removeObserver()移除,一旦Subject发生change(),就会通知所有注册的Observer,这样就起到了一个通知的作用,这样会有个不好的影响就是,有可能主题可能更新了许多内容,并且会将这些内容全部下发给Observer,但是并不是每个Observer都需要这些全部的数据,所以这个时候就可以考虑在Subject中增加一些getter,让Observer自己来取数据,Subject只需要通知Observer有新的数据,Observer根据自己的业务来获取数据,但是这样做也有不好的地方,Subject需要暴露更多的内容给Observer,Observer必须知道Subject的业务接口才能获取自己需要的东西,这就导致耦合度增加了。
Java内置的观察者模式
- Observable.java
- Observer.java
1 | public class JavaSubject extends Observable { |
1 | public class JavaObserver implements Observer { |
- Java 内置了观察者模式的方法,通过继承Observable和实现Observer,就能实现这个设计模式,不过Java内置的Observable,并不是一个接口,这就意味着必须要继承这个父类,然而实际情况中,如果Observer需要继承其他类时,这就很难做出抉择,而且Observable的setchanged()方法是protect的,那就意味着只有Observable的子类才能使用,除非你是Observable的子类,否则你将无法创建Observable实例,并把它组合到自己的类中来。这就违反了设计模式中的少用继承,多用组合的原则。不过,无论怎样,在了解这个模式以后,会知道在什么时候去用什么样的实现。