观察者模式解析
Posted astrobin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式解析相关的知识,希望对你有一定的参考价值。
一、观察者模式概述
观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
观察者模式主要由以下四个部分组成:
1) 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。
2) 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。
3) 具体目标角色(Concrete Subject):将有关状态存入各个Concrete Observer对象。当它的状态发生改变时, 向它的各个观察者发出通知。
4) 具体观察者角色(Concrete Observer):存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向Concrete Subject对象的引用。
观察者模式符合接口隔离原则,实现了对象之间的松散耦合,其UML图示如下:
二、为什么使用观察者模式
观察者模式在实际项目中使用的也是非常频繁的,它最常用的地方是GUI系统、订阅——发布系统等。因为这个模式的一个重要作用就是解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。以GUI系统来说,应用的UI具有易变性,尤其是前期随着业务的改变或者产品的需求修改,应用界面也经常性变化,但是业务逻辑基本变化不大,此时,GUI系统需要一套机制来应对这种情况,使得UI层与具体的业务逻辑解耦,观察者模式此时就派上用场了。观察者模式又被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
应用示例:
介绍
- 这是一个用于拦截android实时短信的库,可以进行短信过滤,得到自己想要的内容,可以用于需要自动填写短信验证码的app项目
功能
- 用于监听当前接收到的短信信息
- 过滤接收到的短信,得到自己想要的内容
首先定义观察者类SmsObserver,包括应用于观察者的一系列方法:
public class SmsObserver extends ContentObserver { private Context mContext; public static final int MSG_RECEIVED_CODE = 1001; private SmsHandler mHandler; /*** *定义三种不同的观察者构造方法 */ public SmsObserver(Activity context, SmsResponseCallback callback,SmsFilter smsFilter) { this(new SmsHandler(callback,smsFilter)); this.mContext = context; } public SmsObserver(Activity context, SmsResponseCallback callback) { this(new SmsHandler(callback)); this.mContext = context; } public SmsObserver(SmsHandler handler) { super(handler); this.mHandler = handler; } /*** * 设置短信过滤器 * @param smsFilter */ public void setSmsFilter(SmsFilter smsFilter) { mHandler.setSmsFilter(smsFilter); } /*** * 注册短信变化观察者的方法 */ public void registerSMSObserver() { Uri uri = Uri.parse("content://sms"); if (mContext != null) { mContext.getContentResolver().registerContentObserver(uri, true, this); } } /*** * 注销短信变化观察者的方法 */ public void unregisterSMSObserver() { if (mContext != null) { mContext.getContentResolver().unregisterContentObserver(this); } if (mHandler != null) { mHandler = null; } } /*** * 设置短信变化的时候发送状态给观察者的方法 */ @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); if (uri.toString().equals("content://sms/raw")) { return; } Uri inboxUri = Uri.parse("content://sms/inbox");//收件箱 try { Cursor c = mContext.getContentResolver().query(inboxUri, null, null, null, "date desc"); if (c != null) { if (c.moveToFirst()) { String address = c.getString(c.getColumnIndex("address")); String body = c.getString(c.getColumnIndex("body")); if (mHandler != null) { mHandler.obtainMessage(MSG_RECEIVED_CODE, new String[]{address, body}) .sendToTarget(); } Log.i(getClass().getName(), "发件人为:" + address + " " + "短信内容为:" + body); } c.close(); } } catch (SecurityException e) { Log.e(getClass().getName(), "获取短信权限失败", e); } catch (Exception e) { e.printStackTrace(); } } }
初始化观察者实例:
SmsObserver smsObserver=new SmsObserver(this, new SmsResponseCallback() { @Override public void onCallbackSmsContent(String smsContent) { //这里接收短信 } }, new VerificationCodeSmsFilter("180"));
注册短信变化监听器
- 在注册监听器以后,短信观察者就已经启动短信变化监听,接下只要接收短信,对短信做处理就可以了
public void registerSMSObserver() { Uri uri = Uri.parse("content://sms"); if (mContext != null) { mContext.getContentResolver().registerContentObserver(uri, true, this); } } smsObserver.registerSMSObserver();
注销短信变化监听器
- 在不需要再使用短信接收功能的时候,请注销短信监听器,不然后续还是可以接收得到短信
/*** * 注销短信变化观察者 */ public void unregisterSMSObserver() { if (mContext != null) { mContext.getContentResolver().unregisterContentObserver(this); } if (mHandler != null) { mHandler = null; } } smsObserver.unregisterSMSObserver();
以上是关于观察者模式解析的主要内容,如果未能解决你的问题,请参考以下文章