Android设计模式之观察者模式与典型应用

在Android开发中,观察者模式是一种应用极为广泛的设计模式,它解决了对象间一对多的依赖关系——当一个对象(被观察者)的状态发生变化时,所有依赖它的对象(观察者)会自动收到通知并更新。这种模式能有效解耦被观察者和观察者,让系统更灵活、可扩展。

一、观察者模式的核心角色

观察者模式包含4个核心角色,它们的分工明确,共同实现“状态变化→自动通知”的逻辑:

角色职责
被观察者(Observable)持有所有观察者的引用,提供注册、移除观察者的方法,以及状态变化时通知所有观察者的方法。
观察者(Observer)定义一个更新接口,当被观察者状态变化时,被观察者会调用此接口通知观察者。
具体被观察者(ConcreteObservable)被观察者的具体实现,维护自身状态,当状态变化时触发通知逻辑。
具体观察者(ConcreteObserver)观察者的具体实现,实现更新接口,在收到通知时执行具体的业务逻辑(如UI刷新、数据处理等)。

二、Android中的观察者模式实现

Android框架中内置了许多基于观察者模式的组件,同时开发者也可以自定义实现。

1. 基于Android原生ObservableObserver的实现(Java)

Android早期提供了java.util.Observable(被观察者基类)和java.util.Observer(观察者接口),可直接使用:

  • 步骤1:定义具体被观察者
    继承Observable,维护状态并在状态变化时调用setChanged()(标记状态已变)和notifyObservers()(通知所有观察者):

    public class WeatherData extends Observable {
        private float temperature; // 温度(被观察的状态)
    
        // 更新温度并通知观察者
        public void setTemperature(float temp) {
            this.temperature = temp;
            setChanged(); // 标记状态已改变(必须调用,否则通知无效)
            notifyObservers(temp); // 通知所有观察者,可传递状态数据
        }
    }
    
  • 步骤2:定义具体观察者
    实现Observer接口,在update()方法中处理被观察者的通知:

    // 示例:显示温度的UI观察者
    public class TemperatureDisplay implements Observer {
        @Override
        public void update(Observable o, Object arg) {
            if (arg instanceof Float) {
                float temperature = (Float) arg;
                // 收到温度更新,执行UI刷新(如TextView显示)
                Log.d("TemperatureDisplay", "当前温度:" + temperature + "℃");
            }
        }
    }
    
  • 步骤3:关联观察者与被观察者
    通过“注册”建立依赖关系,被观察者状态变化时,观察者自动响应:

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            
            // 创建被观察者
            WeatherData weatherData = new WeatherData();
            // 创建观察者
            TemperatureDisplay display = new TemperatureDisplay();
            // 注册观察者
            weatherData.addObserver(display);
            
            // 模拟温度变化,此时观察者会收到通知
            weatherData.setTemperature(25.5f); // 输出:当前温度:25.5℃
        }
    }
    
2. Android中的“观察者模式”典型应用

除了自定义实现,Android框架中大量场景基于观察者模式设计,例如:

  • ListView/RecyclerView的Adapter
    当数据发生变化时,调用notifyDataSetChanged(),ListView会自动刷新UI。这里Adapter是被观察者,ListView的内部布局是观察者——数据变化→通知UI更新,本质是观察者模式的变种。

  • BroadcastReceiver(广播)

    • 广播发送者(如sendBroadcast())是被观察者;
    • 广播接收者(BroadcastReceiver)是观察者,通过registerReceiver()注册,当广播发送时,接收者的onReceive()会被回调。
  • DataBinding双向绑定
    当数据模型(ViewModel)的字段变化时,UI会自动更新;反之,UI输入变化也会同步到数据模型。这里数据模型是被观察者,UI控件是观察者,通过ObservableField等实现自动通知。

  • RxJava/RxAndroid
    核心思想是“观察者订阅被观察者”,被观察者(Observable)发送事件,观察者(Observer)接收并处理,是观察者模式的高级扩展,支持线程切换、事件转换等复杂操作。

3. 自定义观察者模式(Kotlin示例)

在Kotlin中,更推荐自定义接口实现观察者模式(避免依赖Java的Observable,更灵活):

// 1. 定义观察者接口
interface Observer {
    fun onUpdate(data: String) // 接收被观察者的通知,参数为状态数据
}

// 2. 定义被观察者接口
interface Observable {
    fun registerObserver(observer: Observer) // 注册观察者
    fun removeObserver(observer: Observer)  // 移除观察者
    fun notifyObservers()                  // 通知所有观察者
}

// 3. 具体被观察者(如新闻发布者)
class NewsPublisher : Observable {
    private val observers = mutableListOf<Observer>()
    private var latestNews: String = ""

    fun setNews(news: String) {
        this.latestNews = news
        notifyObservers() // 新闻更新,通知所有观察者
    }

    override fun registerObserver(observer: Observer) {
        observers.add(observer)
    }

    override fun removeObserver(observer: Observer) {
        observers.remove(observer)
    }

    override fun notifyObservers() {
        observers.forEach { it.onUpdate(latestNews) } // 逐个通知观察者
    }
}

// 4. 具体观察者(如新闻读者)
class NewsReader(private val name: String) : Observer {
    override fun onUpdate(data: String) {
        println("$name 收到新闻:$data")
    }
}

// 使用示例
fun main() {
    val publisher = NewsPublisher()
    val reader1 = NewsReader("读者A")
    val reader2 = NewsReader("读者B")

    publisher.registerObserver(reader1)
    publisher.registerObserver(reader2)

    publisher.setNews("Android观察者模式详解发布!") 
    // 输出:
    // 读者A 收到新闻:Android观察者模式详解发布!
    // 读者B 收到新闻:Android观察者模式详解发布!
}

三、观察者模式的优缺点

  • 优点

    1. 解耦被观察者和观察者:两者无需知道对方的具体实现,只需依赖接口,便于扩展(新增观察者时无需修改被观察者)。
    2. 支持广播通知:被观察者状态变化时,所有相关观察者都会收到通知,适合“一对多”场景。
  • 缺点

    1. 通知可能存在延迟:如果观察者数量过多,通知过程可能耗时,影响性能(需注意避免在主线程做耗时操作)。
    2. 可能导致循环依赖:若观察者和被观察者相互引用,可能引发内存泄漏(如Android中需在onDestroy移除观察者)。

四、Android开发中的注意事项

  1. 避免内存泄漏
    被观察者通常持有观察者的强引用,若观察者是Activity/Fragment,需在生命周期结束前(如onDestroy)调用removeObserver(),否则被观察者会导致Activity无法被回收。

  2. 线程安全
    注册/移除观察者的操作需在同一线程(如主线程),或通过同步锁保证线程安全,避免并发修改观察者列表导致异常。

  3. 按需通知
    被观察者应仅在状态“真正变化”时通知观察者(如Java的Observable需调用setChanged()),避免无效通知浪费资源。

总结

观察者模式是Android开发中“解耦状态变化与响应逻辑”的核心模式,从基础的UI刷新到复杂的事件驱动(如RxJava),都能看到它的影子。掌握它的核心思想(“一对多依赖+自动通知”),能帮助我们设计更灵活、可维护的Android应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值