字节跳动一面,介绍一下什么是观察者模式?如何实现观察者模式?
观察者模式,属于行为模式的一种,定义了一种一对多的依赖关系,可以让多个观察者同时监听某个主题对象,当这个主题对象的状态发生变化的时候,就会通知所有的观察者对象,然后这些观察者对象就会自动更新自己。
观察者模式在很多场景中都有所使用,例如事件处理系统、发布/订阅系统等。
如何实现一个观察者模式?
观察者模式通常情况下涉及到如下的几个对象
- 主题(Subject):这个主题对象就是被观察的对象,它维护了一个观察者的列表,当其状态发生变化的时候,就会通知这些观察者。
- 观察者(Observer):这是一个抽象类或者是一个接口,它其中定义了一个更新的方法,当主题对象发生变化的时候,会调用这个方法进行更新操作。
- 具体主题对象:这个对象就是主题对象的具体实现类,它维护了对象的状态,然后再这个对象状态发生变化的时候去通知观察者进行更新操作。
- 具体观察者:实现了观察者的接口或者是抽象类,然后当主题对象状态发生变化的时候,去调用更新方法来进行更新操作。
下面我们就来看看在Java中如何实现一个观察者模式。
第一步、定义观察者接口
public interface Observer {
void update(String message);
}
第二步、定义主题接口
import java.util.ArrayList;
import java.util.List;
public class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
protected void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
第三步、具体的主题实现类
public class ConcreteSubject extends Subject {
private String state;
public void setState(String state) {
this.state = state;
notifyObservers(state);
}
public String getState() {
return state;
}
}
第四步、具体的观察者实现类
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received update: " + message);
}
}
测试观察者模式
public class ObserverPatternTest {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("Observer 1");
Observer observer2 = new ConcreteObserver("Observer 2");
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.setState("State 1");
subject.setState("State 2");
}
}
在上面代码中定义了两个观察者分别是observer1,observer2。然后将这个两个观察者添加到了ConcreteSubject主题类中,这时候,调用了subject.setState("State 1");方法对主题的状态进行了修改,这个时候我们就会看到控制台中会有观察者的update()方法输出。
观察者模式的使用场景
观察者模式在很多场景中都有所使用,尤其在一些需要进行一对多的通知场景中。下面是一些观察者模式的常用场景。
GUI事件处理系统
在图形页面系统中,观察者模式被用来处理系统的事件操作,例如按钮、文本框等控件作为主题变化的时候都需要通知到观察者,而这里所谓的观察者其实就是这些操作的事件监听器,用来处理操作事件。
数据模型与视图分离
在MVC架构模型中,Model其实就是可以看做一个主题,而View就是观察者,当模型发生变化的时候,就会通知视图层来更新显示的内容,从而实现模型与视图之间的解耦。
推送通知系统
在消息推送系统中,服务器就是一个主题对象,而客户端就是作为观察者,当服务器中有新的通知的时候,就会立即推送到各个客户端中,例如新闻消息的推送。
发布订阅系统
在消息队列中系统中,我们经常会听到发布者和订阅者的关系其实就是一个观察者模式的实现。当订阅者订阅了某个消息主题的时候,发布者往这个主题中发送了消息之后,订阅者就会立即收到消息并且做出反应。
日志监控系统
在分布式系统中,各个组件所产生的日志也可以看做一个主题,而系统监控其实就是一个观察者,当日志信息发生变化的时候,就相当于主题变化,而监控观察者就会立即对这些数据进行分析。
缓存的更新
我们知道在很多缓存操作中都存在类似于一个Watch机制,这个Watch机制就是一个观察者模式,当数据变化的时候就会通知其他的参与者数据发生了变化。需要对数据进行更新操作。
总结
在这些例子中,我们可以看出观察者模式的使用场景就是基于动态变化解耦操作,以其独特的灵活性与扩展性来实现系统的解耦操作。