观察者模式又叫订阅—发布模式,它的主要作用就是解耦,将观察者和被观察者解耦,使它们的依赖性变的更小。在这个模式中主要就是被观察者通知所有观察者发生改变,及时的更新。Listview的notifyDataSetChanged()改变界面、BroadcastRecevier也是运用此设计模式。
角色介绍
Subject:抽象主题,被观察者(Observable)的角色,抽象主题角色把所有观察者对象的引用保存在一个集合里,每个主题都可以有任意数量的观擦者,抽象主题提供一个接口,可以增加、删除观察者对象。
ConcreteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发出通知,具体主题角色又叫具体被观察者(ConcreteObservable)角色。
Observer:抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知时更新自己。
ConcreteObservre:具体的观察者,该角色实现抽象观察者所定义的更新接口,以便在主题的转态发生变化时更新自己的状态。
下面我们来实现一个例子
抽象观察者
当被观察者发生变化时,观察者进行的行为动作,提供一个统一的方法名便于被调用,参数自己定义
/** * Created by fhm on 2017/5/4. * 观察者的接口 */ public interface Observer { /**** *当观察者发生变化时,观察者进行的行为动作 * ***/ void action(Context context,Object... objects); }具体的观察者
/**** * * * ***/ public class ObserActivity extends AppCompatActivity implements Observer { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_obser); initReceiver(); } public void initReceiver() { AlarmObservable.getInstance(this).registerObserver(this); } @Override public void action(Context context, Object... objects) { // Toast.makeText(context, "MainActivity已更新", Toast.LENGTH_SHORT).show(); Log.e(this.getClass().getName(), "action" + objects[0].toString() + "MainActivity已更新"); } @Override protected void onDestroy() { super.onDestroy(); AlarmObservable.getInstance(this).unRristerObserver(this); } }抽象的被观察者
功能:注册观察者、注销观察者、提醒观察者进行动作更新
/** * Created by fhm on 2017/5/3. * 被观察者对象 * * @param <T> */ public abstract class Observable<T> { public final ArrayList<T> observerList = new ArrayList<>(); /** * 注册观察者 */ public void registerObserver(T t) { checkNull(t); observerList.add(t); } /** * 注销观察者 * * @param t */ public void unRristerObserver(T t) { checkNull(t); observerList.remove(t); } /** * 判断所传的观察者是否为空 */ private void checkNull(T t) { if (t == null) { throw new NullPointerException(); } } /*** * 通知观察者做出行为改变 ***/ public abstract void notifyObservers(Object... objects); }具体的被观察者
/** * Created by fhm on 2017/5/4. * 被观察者对象 */ public class AlarmObservable extends Observable<Observer> { private static AlarmObservable mAlarmObservable = null; private Context mContext; public AlarmObservable(Context mContext) { this.mContext = mContext; } public static AlarmObservable getInstance(Context mContext) { if (mAlarmObservable == null) { mAlarmObservable = new AlarmObservable(mContext); } return mAlarmObservable; } @Override public void notifyObservers(Object... objects) { for (Observer observer : observerList) { if (observer != null) { observer.action(mContext,objects); } } } }提醒观察者更新
public class ObservableActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AlarmObservable.getInstance(this).notifyObservers(this,"你该更新了"); } }一步一步的,观察者模式大致就是这个样子,需要自己好好去理解这个思想。
但是,到真正项目的使用的时候,建议使用别人开发的轮子。例如:EventBus和Otto。
再多说一下,其实,观察者模式和广播机制很像,但是,观察者模式消耗比广播低,因此,假如仅仅是App内部的提醒更新可以使用观察者模式,但是App之间的提醒更新仍然使用广播。
有兴趣的可以看看EventBus的使用。
EventBus使用详解(一)——初步使用EventBus