一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子,比如,邮件订阅、RSS Feeds,本质上都是观察者模式。
观察者模式是一种行为型设计模式,主要解决类或对象之间的交互问题。它的定义是:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会得到通知并自动更新。
观察者模式是一个比较抽象的模式,根据不同的应用场景和需求,有完全不同的实现方式。这里我们以最经典的一种实现方式来实现。
定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
使用场景
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
类图
代码实现
自己实现
Observer
public interface Observer {
void update(String message);
}
Observer1
public class Observer1 implements Observer {
@Override
public void update(String message) {
System.out.println("Observer1:" + message);
}
}
Observer2
public class Observer2 implements Observer {
@Override
public void update(String message) {
System.out.println("Observer2:" + message);
}
}
Subject
public class Subject {
private final List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
this.observers.add(observer);
}
public void removeObserver(Observer observer) {
this.observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
Main
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();
Observer1 observer1 = new Observer1();
Observer2 observer2 = new Observer2();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers("hello");
subject.removeObserver(observer2);
subject.notifyObservers("hi");
}
}
通过JDK实现
这里以报纸订阅为例 Reader
public class Reader implements Observer {
private final String name;
public Reader(String name) {
this.name = name;
}
@Override
public void update(Observable observable, Object message) {
System.out.println(name + ": " + message);
}
}
NewsPaper
public class NewsPaper extends Observable {
private String content;
public void setContent(String content) {
this.content = content;
setChanged();
notifyObservers(content);
}
public String getContent() {
return content;
}
}
Main
public class Main {
public static void main(String[] args) throws InterruptedException {
NewsPaper newsPaper = new NewsPaper();
Reader reader1 = new Reader("reader1");
Reader reader2 = new Reader("reader2");
Reader reader3 = new Reader("reader3");
newsPaper.addObserver(reader1);
newsPaper.addObserver(reader2);
newsPaper.addObserver(reader3);
newsPaper.setContent("hello");
newsPaper.deleteObserver(reader3);
newsPaper.setContent("hi");
}
}
上面的代码算是观察者模式的“模板代码”,只能反映大体的设计思路。在真实的软件开发中,并不需要照搬上面的模板代码。观察者模式的实现方法各式各样,函数、类的命名等会根据业务场景的不同有很大的差别。