Android设计模式之观察者模式
上一篇讲述了单例模式,简单,理解起来也不会太困难,接下来继续讲一下观察者模式
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己
看定义,依然会有点懵逼,待会还是看实际代码吧。。。
观察者模式的特点:
1.它实现了 Subject 和 Observer 之间的松耦合,Subject只知道观察者实现了 Observer 接口,主题不需要知道具体的类是谁、做了些什么或其他任何细节。
2.任何时候我们都可以增加新的观察者。
3.因为主题唯一依赖的东西是一个实现Observer 接口的对象列表,所以我们可以随时增加观察者,同样的,也可以在任何时候删除观察者,当然更不用去关心观察者的类型,只要实现了Observer接口即可,Subject 最后只会发通知给实现了 Observer 接口的观察者。
4.Subject 和 Observer 之间实现松耦合之后,双方代码的修改都不会影响到另外一方,当然前提是双方得遵守接口的规范。
适用环境:
首先第一个,创建一个目标父类Subject
1 /* 2 * 创 建 者: ouyangshengduo 3 * 创建时间: 2017年3月31日 4 * 文件名称: Subject.java 5 * 版权信息: 2017 Edan. All rights reserved. 6 * 文件描述: 观察者模式中的目标父类,管理观察者 7 */ 8 package com.oysd.model.observer; 9 10 import java.util.ArrayList; 11 import java.util.List; 12 13 public class Subject { 14 15 /** 16 * 声明并初始化管理观察者的集合 17 */ 18 private List<Observer> observers = new ArrayList<Observer>(); 19 20 21 /** 22 * 注册观察者方法 23 * @param observer 24 */ 25 public void attach(Observer observer){ 26 observers.add(observer); 27 } 28 29 /** 30 * 移除特定的观察者 31 * @param observer 32 */ 33 public void detach(Observer observer){ 34 observers.remove(observer); 35 } 36 37 /** 38 * 通知所有注册的观察者 39 */ 40 public void notifyObserver(){ 41 for(Observer observer : observers){ 42 observer.update(this); 43 } 44 } 45 46 47 48 }
创建观察者的接口Observer
1 /* 2 * 创 建 者: ouyangshengduo 3 * 创建时间: 2017年3月31日 4 * 文件名称: Observer.java 5 * 版权信息: 2017 Edan. All rights reserved. 6 * 文件描述: 观察者接口 7 */ 8 package com.oysd.model.observer; 9 10 public interface Observer { 11 12 /** 13 * 订阅信息更新通知 14 * @param subject 15 */ 16 public void update(Subject subject); 17 }
创建具体目标对象ConcreteSubject
1 /* 2 * 创 建 者: ouyangshengduo 3 * 创建时间: 2017年3月31日 4 * 文件名称: ConcreteSubject.java 5 * 版权信息: 2017 Edan. All rights reserved. 6 * 文件描述: 具体的目标类 7 */ 8 package com.oysd.model.observer; 9 10 public class ConcreteSubject extends Subject { 11 12 //订阅信息 13 private String notifyInfo; 14 15 public String getNotifyInfo() { 16 return notifyInfo; 17 } 18 19 20 //订阅信息的更改 21 public void setNotifyInfo(String notifyInfo) { 22 this.notifyInfo = notifyInfo; 23 24 this.notifyObserver(); 25 } 26 27 28 29 }
创建具体的观察者对象ConcreteObserver
1 /* 2 * 创 建 者: ouyangshengduo 3 * 创建时间: 2017年3月31日 4 * 文件名称: ConcreteObserver.java 5 * 版权信息: 2017 Edan. All rights reserved. 6 * 文件描述: 具体的观察者对象 7 */ 8 package com.oysd.model.observer; 9 10 public class ConcreteObserver implements Observer { 11 //观察者名字 12 private String observerName; 13 14 //观察者订阅信息 15 private String notifyInfo; 16 17 //观察者处理信息 18 private String excuteInfo; 19 20 21 @Override 22 public void update(Subject subject) { 23 // TODO Auto-generated method stub 24 25 notifyInfo = ((ConcreteSubject) subject).getNotifyInfo(); 26 System.out.println(observerName + "收到" + notifyInfo + "," + excuteInfo); 27 28 } 29 30 31 public String getObserverName() { 32 return observerName; 33 } 34 35 36 public void setObserverName(String observerName) { 37 this.observerName = observerName; 38 } 39 40 41 public String getNotifyInfo() { 42 return notifyInfo; 43 } 44 45 46 public void setNotifyInfo(String notifyInfo) { 47 this.notifyInfo = notifyInfo; 48 } 49 50 51 public String getExcuteInfo() { 52 return excuteInfo; 53 } 54 55 56 public void setExcuteInfo(String excuteInfo) { 57 this.excuteInfo = excuteInfo; 58 } 59 60 61 62 }
新建一个测试类Client
1 /* 2 * 创 建 者: ouyangshengduo 3 * 创建时间: 2017年3月31日 4 * 文件名称: Client.java 5 * 版权信息: 2017 Edan. All rights reserved. 6 * 文件描述: 7 */ 8 package com.oysd.model.observer; 9 10 public class Client { 11 12 public static void main(String[] args) { 13 // TODO Auto-generated method stub 14 15 16 //第一步:创建目标实例 17 ConcreteSubject subject = new ConcreteSubject(); 18 19 //第二步:创建观察者实例 20 ConcreteObserver observer1 = new ConcreteObserver(); 21 observer1.setObserverName("observer1"); 22 observer1.setExcuteInfo("observer1处理信息"); 23 24 ConcreteObserver observer2 = new ConcreteObserver(); 25 observer2.setObserverName("observer2"); 26 observer2.setExcuteInfo("observer2处理信息"); 27 28 //第三步:注册观察者 29 subject.attach(observer1); 30 subject.attach(observer2); 31 32 //第四步:订阅信息发生更改或更新 33 subject.setNotifyInfo("订阅信息发生更改"); 34 } 35 36 }
运行结果:
1 observer1收到订阅信息发生更改,observer1 处理信息 2 observer2收到订阅信息发生更改,observer2处理信息
综上,观察者模式的通用写法就写完了
观察者模式又分推/拉模式,通用写法是拉模式
所谓拉模式就是目标类不知道观察者想要什么信息,就整个都获取,然后想要什么 就拿什么,
observer.update(this);就是把这个对象都返回
而推模式,就是目标类知道观察者想要什么信息,就直接发送特定的信息,那么就更改传入参数,就可以由拉模式改成推模式
observer.update(para);
引入观察者模式的时候,使用者要充分考虑运行环境后,实际情况实际分析,也不能盲目使用。