【设计模式】【观察者模式】实例

发布于:2025-09-12 ⋅ 阅读:(18) ⋅ 点赞:(0)

一对多的统一监听 —— 这就是 观察者模式(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 {
    @Override
    public void onEvent(String event) {
        System.out.println("LoggingListener 收到事件: " + event);
    }
}

// 具体监听器 B
class AlertListener implements EventListener {
    @Override
    public 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() {
    @Override
    public 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() {
    @Override
    public 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()) {
        @Override
        public void onChange(boolean selfChange) {
            Log.d("Observer", "相册数据变化了!");
        }
    }
);

✅ 总结

在 Android 里,一对多统一监听(观察者模式)的典型实现有:

  1. BroadcastReceiver(广播机制)

  2. LiveData.observe()

  3. RecyclerView.AdapterDataObserver

  4. ContentObserver

  5. EventBus/Flow/RxJava

这些都属于 统一监听回调的一对多场景


Android 开发里,观察者模式(Observer Pattern)非常常见,主要用于 “一对多”通知的场景:当一个对象(被观察者/Subject)状态变化时,会自动通知所有依赖它的对象(观察者/Observer),从而实现解耦。


🔹 为什么要用观察者模式?

  1. 解耦合:观察者不需要知道被观察者的内部实现,只关心变化。

  2. 灵活扩展:可以随时增加/移除观察者,不需要修改被观察者逻辑。

  3. 统一通知机制:避免手动在多个地方写重复的刷新或回调。


🔹 在 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();
    };

    @Override
    protected void onStart() {
        super.onStart();
        NetworkManager.addNetworkObserver(networkObserver);
    }

    @Override
    protected void onStop() {
        super.onStop();
        NetworkManager.removeNetworkObserver(networkObserver);
    }
}

这样就实现了一个简单的观察者封装:

  • 解耦:NetworkManager 不关心谁在监听。

  • 可复用:任意页面都能监听网络变化。


🔹 总结

在 Android 里,观察者模式适用于:

  • 数据驱动 UI(LiveData、Flow、RxJava)

  • 组件通信(EventBus、全局状态监听)

  • 自定义控件封装(播放器、下载器、网络监控等)

👉 适合所有 “一个地方变化,多个地方要响应” 的场景。


网站公告

今日签到

点亮在社区的每一天
去签到