首页 > 代码库 > [Android&Java]浅谈设计模式-代码篇:观察者模式Observer

[Android&Java]浅谈设计模式-代码篇:观察者模式Observer

观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐、电子产品、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);
		}
	}

}

5.最后的效果图

技术分享


总结:观察者模式 就是 定义了 一系列对象之间的一对多关系。当一个对象改变状态,其它依赖者都会收到通知。


下载demo的链接

在推荐相关的博客:1.设计模式之七 --- 观察者模式(Observer)

     2.Android Observer观察者模式

-------------------------------------------------------------------------------------更新线-----------------------------------------------------------------------------------------------------

时间:2015年7月24日

关于观察者模式在我们代码中,实际情况往往更加复杂。可能会有多重的组合,由于在java中Observable是一个抽象类。是一个类而不是接口。这使我们想要灵活的使用它比較困难,由于java类仅仅能继承一个类,不能像接口一样,多重继承。这也就是说我们最好自己可以实现类似的接口 去替代他。我在推荐的博客中的第一篇就是这么做的可以学习一下。



[Android&amp;Java]浅谈设计模式-代码篇:观察者模式Observer