观察者,就如同一个人,对很多东西都感兴趣,就好像音乐、电子产品、Game、股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们。在代码中,我们也有这样的一种方式来设计一些好玩的思想来。今天就写个Demo来描述一下这种思想,用java内置的Observer来实现这一思想。
好,程序员是不善言语的,看代码先。
1.demo的结构:
2.先创建我们的主题类Subject,他就是我们本demo的明星类,继承了Observable,顾名思义,就是被观察的类 ,其他观察者对他可是虎视眈眈哦(其实包括你哦)
/** * 定义一个主题类 * @author jan */ public class Subject extends Observable implements Parcelable { private int id; private String name; private String message; public Subject(){} public Subject(Parcel parcel){ this.id = parcel.readInt(); this.name = parcel.readString(); this.message = parcel.readString(); } public int getId() { return id; } public void setId(int id) { this.id = id; notifyChanged(); } public String getName() { return name; } public void setName(String name) { this.name = name; notifyChanged(); } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; notifyChanged(); } /** * 数据改变后,通知我们的订阅该主题的“观察者”数据已经更新 */ private void notifyChanged(){ setChanged(); notifyObservers(); } @Override public String toString() { return "Subject [id=" + id + ", name=" + name + ", message=" + message + "]"; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.id); dest.writeString(name); dest.writeString(message); } public static final Parcelable.Creator<Subject> CREATOR = new Creator<Subject>() { @Override public Subject[] newArray(int size) { return new Subject[size]; } @Override public Subject createFromParcel(Parcel source) { return new Subject(source); } }; }3.嗯,下面就说说我们的观察者Bean先生吧,首先他必须要有个身份,不然怎么叫观察者,他要实现我们的Observer接口,和他的update方法:这是接收最新动态的入口哦!
/** * 这是bean先生,一位订阅者对象 */ public class ObserverBean implements Observer { private Handler hanlder; private Subject subjcet; public ObserverBean(Handler handler){ this.hanlder = handler; } public Subject getSubjcet() { return subjcet; } public void setSubjcet(Subject subjcet) { this.subjcet = subjcet; } @Override public void update(Observable observable, Object data) { this.subjcet = (Subject) observable; Log.i("ObserverBean", "主题已经更新:"+this.subjcet.toString()); if(hanlder!=null){ Message msg = hanlder.obtainMessage(2); msg.obj = subjcet; msg.sendToTarget(); } } }4.我们的主界面来了,哈哈这个Activity 也是一名观察者哦,一名观察者怎么够,至少2个吧,废话少说,看代码。
/** * 观察者模式的一种使用方式,在这里主要的功能是显示我们感兴趣的主题如何改变并通知他们的订阅者,即观察者 * 本例子的效果不是重点,主要是增加对Observer的了解。 * @author jan * Date:2015年7月22日 20:27:01 */ public class ObserverActivity extends Activity implements Observer { private static final String TAG = "ObserverActivity"; // 显示改变的主题内容 private TextView mSubText1; private TextView mSubText2; // 被订阅的主题 private Subject mSubject; private UpdateRunnable runnable; // 观察者实体类,我们另一个订阅对象 private ObserverBean bean; private Handler mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { if (msg.what == 1) { // 更新ObserverActivity的收到的主题 Subject sj1 = (Subject) msg.obj; mSubText1.setText(sj1.getId() + "\n" + sj1.getName() + "\n" + sj1.getMessage()); return true; } else if (msg.what == 2) { // 更新bean先生收到的主题内容 Subject sj2 = (Subject) msg.obj; mSubText2.setText(sj2.getId() + "\n" + sj2.getName() + "\n" + sj2.getMessage()); return true; } return false; } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mSubText1 = (TextView) findViewById(R.id.subject_id_1); mSubText2 = (TextView) findViewById(R.id.subject_id_2); // 创建另一个订阅者,bean先生 bean = new ObserverBean(mHandler); // 生成主题的实例 mSubject = new Subject(); bean.setSubjcet(mSubject); // 主题对象 把 观察者 加入进来,建立关联,一个主题可能有几个人感兴趣,如下,添加了2个观众 mSubject.addObserver(bean); mSubject.addObserver(this); runnable = new UpdateRunnable(); mHandler.postDelayed(runnable, 1000); } // 如果主题内容变化了,会触发该方法,我们在这里更新显示主题的最新内容 @Override public void update(Observable observable, Object data) { Subject sj = null; if (observable instanceof Subject) { sj = (Subject) observable; Log.d(TAG, "Subject-->"+sj.toString()); Message msg = mHandler.obtainMessage(1); msg.obj = sj; msg.sendToTarget(); } } @Override protected void onDestroy() { super.onDestroy(); mHandler.removeCallbacks(runnable); mSubject.deleteObserver(this); mSubject.deleteObserver(bean); } /** * 定时每隔一秒改变主题的内容 * @author jan */ class UpdateRunnable implements Runnable { int i = 0; @Override public void run() { if (mSubject != null) { i++; mSubject.setId(i); mSubject.setName(i + "活动日志"); mSubject.setMessage("今晚打老虎--" + i); } mHandler.postDelayed(this, 1000); } } }
总结:观察者模式 就是 定义了 一系列对象之间的一对多关系。当一个对象改变状态,其他依赖者都会收到通知。
下载demo的链接
在推荐相关的博客:1.设计模式之七 --- 观察者模式(Observer)
2.Android Observer观察者模式
-------------------------------------------------------------------------------------更新线-----------------------------------------------------------------------------------------------------
时间:2015年7月24日
关于观察者模式在我们代码中,实际情况往往更加复杂,可能会有多重的组合,因为在java中Observable是一个抽象类,是一个类而不是接口,这使我们想要灵活的使用它比较困难,因为java类只能继承一个类,不能像接口一样,多重继承,这也就是说我们最好自己能够实现类似的接口 去替代他。我在推荐的博客中的第一篇就是这么做的可以学习一下。