观察者模式:
定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会自动收到通知并更新
设计原则:
为了交互对象之间的松耦合设计而努力(降低了对象之间的互相依赖)
1. 当两个对象之间松耦合,它们依然可以交互,但是不清楚彼此间的细节;
2. 一对多的关系是如何关联的: 一方面 "一个" 主题拥有状态,并且能够控制这些状态;另一方面,有 "多个" 观察者都能够接收并使用这些状态,虽然它们并不具有这些状态;
3. 期间的依赖是如何产生的: 主题是状态的拥有者,观察者依赖状态的改变而刷新数据,但是以什么样的方式刷新数据与状态无关;
观察者模式简单的UML:
具体实现:
1. 创建一个主题类来控制监听:
public class Constants { private List<GetFiles> list; //存放要监听的对象的集合 private Object obj; //要传的参数,这里先定义成obj类型 public Constants(){ if(list == null){ list = new ArrayList<>(); } } public void addRegister(GetFiles observer){ //添加到监听 list.add(observer); } public void removeRegister(GetFiles observer){ //移除监听 int i = list.indexOf(observer); if(i >= 0){ list.remove(i); } } public void onChange(){ //假设改变的时候就触发这个方法 for (int i = 0; i < list.size(); i++) { GetFiles getFiles = list.get(i); getFiles.updata(obj); } }
2. 定义观察者的接口:
public interface GetFiles { void updata(Object obj);
3. 观察者具体实现:
public class GetVideoFiles implements GetFiles { private Constants constants;//主题对象 public GetVideoFiles(Constants constants){ this.constants = constants;//拿到主题对象,移除监听的时候可以用到 constants.addRegister(this);//添加注册监听 } @Override public void updata(Object obj) { //更新数据 } public void register(){ constants.removeRegister(this); }
4. 当然为了方便,可以将 GetFiles 接口当做 Constants 主题的一个内部接口,然后再在其里面提供一个 setGetFiles() 的方法,将对象传过去,然后就可以直接调用方法 getFiles.updata(obj)了,我一般的接口回调都是这么写的。
补充:
观察者模式作为JDK中使用最多的模式之一,平时也会经常遇到,比如:activity 与 fragment 的交互,activity 与 broadcast 的交互,按钮监听,文件监听fileobserver等等。当然观察者模式除了我上面说得 pull 的方式之外,还有一种就是通过 get 的方式,只通知改变,不传递数据,观察者要什么数据就去主题那里取什么数据。