概念与介绍
定义
多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖于它的对象都能得到通知并自动更新。
观察者模式有时又称作发布-订阅模式,属于行为型模式。
应用场景
一个对象的改变将导致其他一个或多个对象也发生改变,但是并不
知道这些对象是谁,也不知道有多少对象将发生改变。
应用举例
1.体育老师吹哨叫大家集合。
2.一声惊雷,外面突然乌云密布,眼看就要下雨,大伙连忙出去收衣服。
(这里,乌云就是一个观察目标,所有晾了衣服的人都是观察者。)
主要优点
1.降低了目标与观察者之间的耦合关系,让耦合的双方都依赖于抽象,
而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
2.目标与观察者之间建立了一套触发机制。
主要缺点
1.目标与观察者之间的依赖关系并没有完全解除(抽象目标与抽象观察者
仍然存在耦合)。如果两者之间存在循环依赖的话,有可能出现因为循
环引用而导致的系统崩溃。
2.当观察者对象很多时,将所有的观察者对象都通知到需要花费大量的
时间。
结构与实现
一、模式的结构
classDiagram
抽象目标Subject <|-- 具体目标ConcreteSubject : Inheritance
抽象目标Subject o-- 抽象观察者Observer : Aggregation
具体观察者ConcreteObserver1 ..|> 抽象观察者Observer : Realization
具体观察者ConcreteObserver2 ..|> 抽象观察者Observer : Realization
class 抽象目标Subject{
#List~Observer~ observers
+add(Observer observer) void
+remove(Observer observer) void
+notifyObserver() void
}
class 抽象观察者Observer{
<<interface>>
+response void
}
class 具体观察者ConcreteObserver1{
+response void
}
class 具体观察者ConcreteObserver2{
+response void
}
class 具体目标ConcreteSubject{
+notifyObserver() void
%% 使用notifyObserver方法()
%% 通知每一个依赖在该具体目标上的具体观察者执行response()
}
(PS:mermaid是代码自动生成的布局,很多地方受限,不能调整。所以后面还是打算放UML图片了)
二、模式的实现
package observer;
//观察者模式
public class ObserverPattern {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer obs1 = new ConcreteObserver1();
Observer obs2 = new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
}
//抽象目标
abstract class Subject {
protected List<Observer> observers = new ArrayList<Observer>();
//增加观察者
public void add(Observer observer) {
observers.add(observer);
}
//删除观察者
public void remove(Observer observer) {
observers.remove(observer);
}
//通知观察者
public abstract void notifyObserver();
}
//具体目标
class ConcreteSubject extends Subject {
public void notifyObserver() {
System.out.println("天上乌云密布...");
System.out.println("--------------");
for (Object obs : observers) {
((Observer) obs).response();
}
}
}
//抽象观察者
interface Observer {
void response(); //反应
}
//具体观察者1
class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("我连忙出去收衣服");
}
}
//具体观察者2
class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("邻居连忙出去收衣服");
}
}
程序运行结果
天上乌云密布...
--------------
我连忙出去收衣服
邻居连忙出去收衣服