设计模式之观察者模式

1.观察者模式的定义

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

2.观察者的使用场景

a.关联行为场景,关联行为是可拆分的,而不是“组合”关系

b.事件多级触发场景

c.跨系统的消息交换场景,如消息队列,事件总线的处理机制

3.观察者模式结构


Subject(抽象主题):被观察者(Observable),抽象主体角色把所有观察者对象的引用保存在一个集合(如ArrayList)里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

ConcreteSubject(具体主题角色):具体被观察者(Concreate Observable),将有关状态存入具体观察者对象;在具体主题的内部状态发生变化时,给所有注册过的观察者发出通知。

Observer(抽象观察者):该角色是观察者的抽象类,它定义了一个更新接口,使得在主题的更改通知时更新自己。

ConcreteObserver(具体观察者):该角色实现了抽象观察者所定义的更新接口,以便在主题状态发生变化时更新自己的状态。

4.观察者模式的简单实现

开发技术前线不仅是个内容发布页面,也支持用户邮箱订阅,会把每周的周报优质内容发送给订阅用户,这种模式就叫做发布-订阅模式,又叫做观察者模式。

下面简单模拟下发布-订阅过程:

//程序员是观察者
		public class Coder implements Observer{
			public String name;
			public Coder(String name){
				this.name = name;
			}
			
			@Override
			public String toString() {
				// TODO Auto-generated method stub
				return "码农: "+name;
			}

			public void update(Observable o, Object arg) {
				System.out.println("Hi,"+name+",DevTechFrontier更新啦,内容:"+arg);
			}
		}


//这个网站是被观察者角色,当它有更新的时候所有观察者都会接到相应的通知
		public class DevTechFrontier extends Observable{
			public void postNewPublication(String content) {
				//表示状态或是内容发生变化
				setChanged();
				//通知所有观察者
				notifyObservers(content);
			}
		}

//测试代码
		public class Test{
			public static void main(String[] args){
				//被观察者的角色
				DevTechFrontier devTechFrontier = new DevTechFrontier();
				//观察者
				Coder mr.simple = new Coder("mr.simple");
				Coder coder1 = new Coder();
				Coder coder2 = new Coder();
				Coder coder3 = new Coder();
				//将所有观察者注册到被观察者对象的观察者列表中
				devTechFrontier.addObserver(mr.simple);
				devTechFrontier.addObserver(coder1);
				devTechFrontier.addObserver(coder2);
				devTechFrontier.addObserver(coder3);
				//发布消息
				devTechFrontier.postNewPublication("新的一期开发技术前线周报发布啦!");
			}
		}

总结:Observer和Observable是JDK内置类型。Observer是抽象的观察者角色,Coder扮演的是具体观察者角色;Observeable是抽象的被观察者角色,DevTechFrontier则是具体的被观察者角色。Coder订阅了DevTechFrontier这个被观察者,当 DevTechFrontier更新时,会遍历所有的观察者(这里是Coder),然后会通知观察者更新消息。即调用了Coder中的update方法,这就达到了一对多的通知功能。对于Coder和DevTechFrontier完全没有耦合,保证了订阅系统的灵活性和可扩展性。

5.BaseAdapter——观察者模式

一直以为所有的适配器都是适配器模式,结果,今天看书才发现。。。原来我错了

当ListView的数据发生变化时,都会调用Adapter的notifyDataSetChanged()方法,这个函数又会调用DataSetObservable的notifyChanged,notifyChanged中遍历所有观察者,并且调用它们的onChanged方法,从而告知观察者发生了变化,在onChanged函数中又调用ListView重新布局的函数使ListView刷新界面,就是观察者模式!!!

6.BroadcastReceiver

BroadcastReceiver是Android的四大组件之一,他作为应用内、进程间的一种重要通信手段,能够将某个消息通过广播的形式传递给它注册的对应广播接收器的对象,接收对象需要通过Context的registerReceiver函数之处到AMS中,当sendBroadcast发送广播是,所有注册了对应的IntentFilter的BroadcastReceiver对象会接收到这个消息,BroadcastReceiver的onReceive()方法就会被调用,这是一个典型的观察者模式。

注: 在广播接收器的onReceive()方法中不可以添加过多的逻辑或任何耗时的操作,因为在广播接收器中不允许开启线程,当onReceive()方法运行了较长时间而没有结束时,程序就会报错。因此,广播接收器更多的是扮  演打开程序其他组件的角色,比如创建一条状态栏通知,或者是开启一个服务等。

总结:Android中大量使用了观察者模式,像View的Listener监听、GPS位置信息监听、BroadcastReceiver等都是基于观察者模式实现的。

7.回调机制

Android中有非常多的地方用到了回调机制,例如Activity的生命周期、按钮的点击事件、线程的run()方法等。

重点:回调机制和观察者模式的区别:

a.观察者模式里面被观察者维护了所有观察者的引用

b.回调机制里只维护了一个引用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值