定义:
观察者模式又叫发布订阅模式,它定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
组成:
Subject(通知者/被观察者):指代的就是那个被观察者,通常由接口或者抽象类实现,常见方法有addObserver/deleteObserver方法用来增删观察者,notifyObservers状态改变时通知观察者
ConcreteSubject (具体通知者/被观察者):这个就是具体的被观察者类,实现上面的Subject接口
Observer (观察者):就是观察Subject的观察者,是个接口,只有1个update()方法,被观察者改变时会被调用,也就是说它可以通过这个方法来获取到被观察者的状态更新
ConcreteObserver (具体观察者类):实现上面的Observer接口
适用场景:
当一个对象状态发生改变,会导致其他对象都发生改变
例子:
(Subject.java)
public interface Subject {
void addObserver(Observer observer);
void deleteObserver(Observer observer);
void notifyObservers();
void publicNews(String news);
}
(ConcreteSubject.java)
public class ConcreteSubject implements Subject {
private ArrayList<Observer> observers;
private String news;
public ConcreteSubject() {
observers = new ArrayList<>();
}
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
int i = observers.indexOf(observer);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(this, news);
}
}
public void publicNews(String news) {
this.news = news;
notifyObservers();
}
}
(Observer.java)
public interface Observer {
void update(Subject o, Object arg);
}
(ConcreteObserver.java)
public class ConcreteObserver implements Observer{
private Subject subject;
public ConcreteObserver(Subject subject){
this.subject = subject;
this.subject.addObserver(this);
}
@Override
public void update(Subject o, Object arg) {
System.out.println("收到的新闻: "+ arg);
}
}
(TestClient.java)
public class TestClient {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
new ConcreteObserver(subject);
subject.publicNews("今天我们的生活怎么样?");
subject.publicNews("为什么有人骑在我们的脖子上?");
}
}
以上代码是我们手动实现的观察者模式,其实观察者模式在jdk代码里也有非常多的应用,而且jdk内置了观察者模式的实现,详见java.util.Observable和java.util.Observer。以下是一些该模式的要点:
1、该模式定义了对象之间一对多的关系。
2、主题(被观察者)用一个共同的接口来更新观察者。
3、有多个观察者时,不可以依赖特定的通知顺序。
4、使用此模式时,你可以从被观察者处推(push)或拉(pull)数据,然后推的方式被认为是更合理的操作。
5、观察者和被观察者之间松耦合,被观察者不知道观察者的细节,只知道观察者实现了观察者接口。