在之前的文章观察者模式中,虽然被观察者并不依赖于观察者,但是被观察者知道观察者的存在,这就出现了一定程度的耦合关系。
我们通常希望一个观察者模式是这样的:
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!");
}
};
该接口内的函数都是回调函数,可以被该接口的实例调用。
我们将该实例传给被观察者,被观察者持有这个实例(监听器)之后就可以通过它调用里面的回调函数,就实现了向观察者的消息通知。
之前被观察者持有的是观察者的引用,现在持有的是观察者送它的监听器,本身并不知道监听器是谁给它的,明显降低了耦合程度。