在之前的文章观察者模式中,虽然被观察者并不依赖于观察者,但是被观察者知道观察者的存在,这就出现了一定程度的耦合关系。
我们通常希望一个观察者模式是这样的:
1.观察者依赖于被观察者,被观察者不依赖于观察者。
2.被观察者最好不知道观察者的存在,既能独立工作,又能减少与观察者的耦合关系。
EventListener.java:
- package com.example.listenertest;
-
- //监听器接口,监听器是该接口的一个实例
- public interface EventListener {
- //回调函数
- void onComplete();
- }
Observer.java:
- package com.example.listenertest;
-
- import android.util.Log;
-
- public class Observer {
-
- public final static String TAG = "ObserverTest";
-
- Subject mSubject;
-
- //观察者构造函数,观察者必须依赖于某个被观察者,并且向其注册监听器
- public Observer(Subject subject){
- mSubject = subject;
- setOBListener();//注册监听器
- }
-
- //监听器,被观察者通过该监听器通知观察者
- EventListener mEventListener = new EventListener() {
- @Override
- public void onComplete() {
- Log.d(TAG, "Subject Complete!");
- }
- };
-
- //向被观察者设置监听器
- void setOBListener(){
- mSubject.setListener(mEventListener);
- }
- }
Subject.java:
- package com.example.listenertest;
-
- import android.util.Log;
-
- public class Subject {
- public final static String TAG = "ObserverTest";
-
- //内置一个监听器,该监听器由观察者赋值
- EventListener mEventListener = null;
-
- //内置监听器赋值方法
- void setListener(EventListener listener){
- mEventListener = listener;
- }
-
- //通知发送方法
- void onNotify(){
- if(mEventListener != null){
- //如果确实注册了监听器,就通过监听器回调观察者的方法
- mEventListener.onComplete();
- }
- }
-
- //模拟的工作内容
- void subjectWork(){
- Log.d(TAG, "subject is working!");
- onNotify();//工作完成了发送通知
- }
- }
MainActivity.java:
- package com.example.listenertest;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import android.os.Bundle;
-
- public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- Subject sub = new Subject();
- Observer ob = new Observer(sub);
- //被观察者开始工作
- sub.subjectWork();
- }
- }
结果:

首先说明一下设计思路。为了降低观察者与被观察者的耦合程度,我们采用一种“监听器”作为观察者与被观察者之间的联系,这样的话被观察者只知道监听器的存在,而不知道观察者的存在,降低了耦合程度。
从源代码中可以看出,监听器是一个接口的实例,该实例由观察者实现。
- //监听器,被观察者通过该监听器通知观察者
- EventListener mEventListener = new EventListener() {
- @Override
- public void onComplete() {
- Log.d(TAG, "Subject Complete!");
- }
- };
该接口内的函数都是回调函数,可以被该接口的实例调用。
我们将该实例传给被观察者,被观察者持有这个实例(监听器)之后就可以通过它调用里面的回调函数,就实现了向观察者的消息通知。
之前被观察者持有的是观察者的引用,现在持有的是观察者送它的监听器,本身并不知道监听器是谁给它的,明显降低了耦合程度。