【设计模式】【观察者模式】实例
一对多的统一监听 —— 这就是 观察者模式(Observer Pattern) 的经典应用场景。
也就是说:
一个事件源(Subject) → 可以注册多个监听器(Observers);
当事件发生时,一次性通知所有监听器;
各监听器通过统一的接口接收回调。
🔧 Java 示例代码
import java.util.ArrayList;
import java.util.List;// 统一监听接口(Observer)
interface EventListener {void onEvent(String event);
}// 事件源(Subject)
class EventSource {private final List<EventListener> listeners = new ArrayList<>();// 添加监听器public void addListener(EventListener listener) {listeners.add(listener);}// 移除监听器public void removeListener(EventListener listener) {listeners.remove(listener);}// 触发事件,通知所有监听器public void triggerEvent(String event) {System.out.println("EventSource: 触发事件 -> " + event);for (EventListener listener : listeners) {listener.onEvent(event);}}
}// 具体监听器 A
class LoggingListener implements EventListener {@Overridepublic void onEvent(String event) {System.out.println("LoggingListener 收到事件: " + event);}
}// 具体监听器 B
class AlertListener implements EventListener {@Overridepublic void onEvent(String event) {System.out.println("AlertListener 收到事件: " + event);}
}// 测试
public class ObserverPatternDemo {public static void main(String[] args) {EventSource source = new EventSource();// 注册多个监听器source.addListener(new LoggingListener());source.addListener(new AlertListener());source.addListener(event -> System.out.println("匿名Listener 收到事件: " + event));// 触发事件source.triggerEvent("用户登录");source.triggerEvent("文件上传");}
}
▶️ 输出结果
EventSource: 触发事件 -> 用户登录
LoggingListener 收到事件: 用户登录
AlertListener 收到事件: 用户登录
匿名Listener 收到事件: 用户登录EventSource: 触发事件 -> 文件上传
LoggingListener 收到事件: 文件上传
AlertListener 收到事件: 文件上传
匿名Listener 收到事件: 文件上传
📌 总结
一对多的统一监听 就是 观察者模式:
Subject(事件源):维护监听器集合;
Observer(监听器):实现统一回调接口;
Notify(通知):事件触发时,循环回调所有监听器。
这样做的好处是:
解耦(事件源无需关心监听器的实现细节);
扩展性好(随时新增/删除监听器);
统一接口(所有监听器用一个回调方法
onEvent
处理)。
Android 里到处都是“一对多统一监听”这种观察者模式的实例,几乎是 核心设计思想之一。下面列几个典型的例子给你:
📌 Android 中的一对多统一监听实例
1. View 的点击事件分发
事件源(Subject):
View
监听器(Observer):
OnClickListener
但这里是 一对一,只能设置一个
OnClickListener
。
👉 不过在 事件总线/广播里是一对多。
2. BroadcastReceiver(广播机制)
这是 Android 里 最标准的一对多统一监听:
事件源:系统/应用发送的广播(Intent)。
观察者:所有注册的
BroadcastReceiver
。当广播触发时,系统会依次通知所有匹配的接收者。
// 注册广播接收器
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {int level = intent.getIntExtra("level", 0);System.out.println("收到电量变化广播: level=" + level);}
}, filter);// 任意地方发广播
Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.putExtra("level", 90);
sendBroadcast(intent);
👉 所有监听 ACTION_BATTERY_CHANGED 的接收器都会同时收到回调。
3. LiveData / Flow / RxJava
事件源:
LiveData<T>
观察者:
Observer<T>
你可以给同一个 LiveData 添加多个观察者,它们会同时收到数据更新。
MutableLiveData<String> liveData = new MutableLiveData<>();// 监听器1
liveData.observe(this, data -> {Log.d("Observer1", "收到数据: " + data);
});// 监听器2
liveData.observe(this, data -> {Log.d("Observer2", "收到数据: " + data);
});// 触发事件
liveData.setValue("新消息来了!");
👉 输出:
Observer1: 收到数据: 新消息来了!
Observer2: 收到数据: 新消息来了!
4. RecyclerView.AdapterDataObserver
事件源:
RecyclerView.Adapter
观察者:
AdapterDataObserver
当数据集变化时,会通知所有观察者(例如 RecyclerView 自己 + 其他订阅者)。
RecyclerView.Adapter adapter = ...;
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {@Overridepublic void onChanged() {Log.d("Observer", "Adapter 数据更新");}
});// 更新数据
adapter.notifyDataSetChanged();
5. ContentObserver
事件源:ContentProvider 数据变化。
观察者:所有注册的
ContentObserver
。
getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,true,new ContentObserver(new Handler()) {@Overridepublic void onChange(boolean selfChange) {Log.d("Observer", "相册数据变化了!");}}
);
✅ 总结
在 Android 里,一对多统一监听(观察者模式)的典型实现有:
BroadcastReceiver(广播机制)
LiveData.observe()
RecyclerView.AdapterDataObserver
ContentObserver
EventBus/Flow/RxJava 等
这些都属于 统一监听回调的一对多场景。
在 Android 开发里,观察者模式(Observer Pattern)非常常见,主要用于 “一对多”通知的场景:当一个对象(被观察者/Subject)状态变化时,会自动通知所有依赖它的对象(观察者/Observer),从而实现解耦。
🔹 为什么要用观察者模式?
解耦合:观察者不需要知道被观察者的内部实现,只关心变化。
灵活扩展:可以随时增加/移除观察者,不需要修改被观察者逻辑。
统一通知机制:避免手动在多个地方写重复的刷新或回调。
🔹 在 Android 中常见的使用场景
1. UI 更新和数据监听
LiveData + Observer(Jetpack):UI 组件(Activity/Fragment)订阅数据,数据变化时自动刷新 UI。
EventBus/RxJava:跨组件事件传递,类似全局观察者模式。
2. 自定义组件封装
例如封装一个 网络状态监听组件:
被观察者:
NetworkManager
(内部监听系统广播/ConnectivityManager)。观察者:Activity/Fragment/自定义 View,需要知道网络是否可用。
这样多个页面只要注册为观察者,就能统一收到网络变化通知。
3. 多模块通信
下载/上传进度监听:下载器作为 Subject,UI 页面作为 Observer。
播放器状态监听:MediaPlayer/ExoPlayer 的状态变化通知给 UI 控件(进度条、播放按钮)。
4. 数据缓存和刷新
比如 Room + LiveData 就是典型观察者模式:数据库数据变更 → LiveData 通知 → UI 自动刷新。
🔹 简单封装示例
假设我们封装一个 全局事件中心,支持任意组件监听和通知。
// 1. 定义观察者接口
public interface Observer<T> {void onUpdate(T data);
}// 2. 被观察者(事件中心)
public class EventBus<T> {private final List<Observer<T>> observers = new ArrayList<>();public void register(Observer<T> observer) {observers.add(observer);}public void unregister(Observer<T> observer) {observers.remove(observer);}public void notifyObservers(T data) {for (Observer<T> observer : observers) {observer.onUpdate(data);}}
}// 3. 使用示例
public class NetworkManager {private static final EventBus<Boolean> eventBus = new EventBus<>();public static void addNetworkObserver(Observer<Boolean> observer) {eventBus.register(observer);}public static void removeNetworkObserver(Observer<Boolean> observer) {eventBus.unregister(observer);}// 系统监听到网络变化时调用public static void onNetworkChanged(boolean available) {eventBus.notifyObservers(available);}
}
在 Activity 中用法:
public class MainActivity extends AppCompatActivity {private final Observer<Boolean> networkObserver = available -> {Toast.makeText(this, available ? "网络可用" : "网络不可用", Toast.LENGTH_SHORT).show();};@Overrideprotected void onStart() {super.onStart();NetworkManager.addNetworkObserver(networkObserver);}@Overrideprotected void onStop() {super.onStop();NetworkManager.removeNetworkObserver(networkObserver);}
}
这样就实现了一个简单的观察者封装:
解耦:NetworkManager 不关心谁在监听。
可复用:任意页面都能监听网络变化。
🔹 总结
在 Android 里,观察者模式适用于:
数据驱动 UI(LiveData、Flow、RxJava)
组件通信(EventBus、全局状态监听)
自定义控件封装(播放器、下载器、网络监控等)
👉 适合所有 “一个地方变化,多个地方要响应” 的场景。