[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.最后的效果图
总结:观察者模式 就是 定义了 一系列对象之间的一对多关系。当一个对象改变状态,其它依赖者都会收到通知。
在推荐相关的博客:1.设计模式之七 --- 观察者模式(Observer)
-------------------------------------------------------------------------------------更新线-----------------------------------------------------------------------------------------------------
时间:2015年7月24日
关于观察者模式在我们代码中,实际情况往往更加复杂。可能会有多重的组合,由于在java中Observable是一个抽象类。是一个类而不是接口。这使我们想要灵活的使用它比較困难,由于java类仅仅能继承一个类,不能像接口一样,多重继承。这也就是说我们最好自己可以实现类似的接口 去替代他。我在推荐的博客中的第一篇就是这么做的可以学习一下。
[Android&Java]浅谈设计模式-代码篇:观察者模式Observer的更多相关文章
- 浅谈PHP代码设计结构
浅谈PHP代码设计结构 您的评价: 还行 收藏该经验 coding多年,各种代码日夜相伴,如何跟代码友好的相处,不光成为职业生涯的一种回应,也是编写者功力的直接显露. 如何看 ...
- 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)
设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...
- 设计模式系列之观察者模式(Observer Pattern)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作 ...
- java设计模式学习笔记--浅谈设计模式
设计模式的目的 编写软件的过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战.设计模式为了让程序具有更好的 1.代码重用性(即:相同功能的代码,不用多次编写) ...
- 浅谈设计模式-visitor访问者模式
先看一个和visitor无关的案例.假设你现在有一个书架,这个书架有两种操作,1添加书籍2阅读每一本书籍的简介. //书架public class Bookcase { List<Book> ...
- 浅谈设计模式--单例模式(Singleton Pattern)
题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...
- Spring源码分析 之浅谈设计模式
一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级 零配置, ...
- 【SSH 基础】浅谈Hibernate--入门篇
Hibernate是什么 Hibernate是一个轻量级的ORMapping框架 ORMapping原理(Object Relational Mapping)就是把对象里面的数据和数据库里面的数据,依 ...
- 浅谈设计模式及python实现
设计模式及Python实现 设计模式是什么? Christopher Alexander:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心.这样你就能一次又一次地使用 ...
随机推荐
- jQuery的deferred对象使用笔记
一.什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作.其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们 ...
- Java 正则表达式提取标签中的属性(src 连接地址)等
public class Test { public static void main(String[] args) { String source = "<p><img ...
- [置顶] Android之服务器编程
这个教程主要是讲解服务器编程的,如果你的应用需要和服务器通信,那就必须了解服务器编程(当然,也许你不需要了解,因为你只开发客户端),Android应用和服务器的通信可以使用Http + JSON来通信 ...
- es6(const、let)
首先我很好奇,明明现代浏览器支持ES6.ES7不是那么好,为何还推行? var let const 有何区别?它们之间的限制又是什么?且听我娓娓道来 1. var 和let的关系,为何推荐let? ( ...
- 微信小程序 - 各种示例
示例更新(后续持续更新): 最后一次更新:2018-11-7 小程序-地图显示(调用高德地图.腾讯App) - (2018-11-1) 小程序-上传图片(上传.预览.展示.删除) - (2018-11 ...
- Java从零开始学十(Arrays类对数组的常用方法)
一.Arrays类常用方法 二.简单例子 package com.pb.demo1; import java.util.Arrays; /* * Arrays工具类的中的几个常用方法 * 1.copy ...
- #define中的“#”和“##”的作用
在#define中,标准只定义了#和##两种操作: #用来把参数转换成字符串: ##则用来连接两个前后两个参数,把它们变成一个字符串.
- 如何在hosts文件添加自己想要解析的网站?及修改hosts的作用
http://union.zhuna.cn/help/144.asp 在Windows2003/XP系统中位于C:\Winnt\System32\Drivers\Etc 目录中,找到host文件. 首 ...
- DOS批处理高级教程
转载-->http://blog.csdn.net/lanbing510/article/details/7461073 前言 本教程主要引用伤脑筋版主的系列文章,同时参考引用[英雄]教程等其他 ...
- windows命令:control命令
Windows的命令列模式下有个非常好用的命令叫做Control.这个命令其实就是控制『控制台』的一个接口.你可以用这个命令直接叫起一些平常要找很久才会找到的窗口.最简单的一个例子,你只要在『开始』 ...