观察者模式--农民的故事

来源:互联网 发布:51内核单片机 编辑:程序博客网 时间:2024/04/20 10:58

刚开始学习Java的就接触观察者模式了,但是总是不太能理解这种模式或者理解的一点不深刻,特别容易忘记。最近搞Android总是遇到RxJava,RxAndroid,毕竟RxJava+RxAndroid+okHttp太火了。为了学习这种框架就得重新搞一下Java的观察者模式了。首先用Java讲一个农民的故事:
话说桃花源的农民都很聪明,耕种的时候都会在老天下雨的时候开始耕种,这样种出来的庄稼会有更好的收成。所以种瓜的农民伯伯、种豆的农民阿姨天天都在观察着老天爷。(老天爷:被观察者)老天爷一下雨,农民伯伯就马上种瓜、农民阿姨马上种豆。(注意:农民伯伯、农民阿姨两人可能基本不认识,两者一点关系都没有)。

首先定义一下农民的行为(观察者)

package com.lxz;/** * 描述:观察者(农民) * 作者:Linxz * 邮箱:lin_xiao_zhang@163.com * 时间: 2017年4月14日 上午11:05:32 * 版本:1.0 */public interface Observer {    /**标记当前观察者是谁*/    public void setName(String name);    /**老天下雨的时候农民的行为*/    public void farmerDo(Object message);}

被观察者(老天爷)

package com.lxz;/** * 描述:被观察者(老天爷) * 作者:Linxz * 邮箱:lin_xiao_zhang@163.com * 时间: 2017年4月14日 上午11:07:52 * 版本:1.0 */public interface Observerable {    /**订阅(将该农民放到观察者的队伍中)*/    public void attach(Observer observer);    /**取消订阅(改农民不再观察我)*/    public void detach(Observer observer);    /**下雨了:通知观察者*/    public void notifyObservers(Object message);}

定义好了农民跟老天爷的行为之后,创建农民跟老天爷实体:
农民实体,农民具备农民的基本属性跟行为(农民的名称,观察老天爷下雨)

package com.lxz;/** * 描述: * 作者:Linxz * 邮箱:lin_xiao_zhang@163.com * 时间: 2017年4月14日 上午11:20:16 * 版本:1.0 */public class Farmer implements Observer{    /**标识我是种瓜的农民伯伯还是种豆的农民阿姨*/    private String name;    @Override    public void setName(String name) {        this.name=name;    }    /**农民的行为*/    @Override    public void farmerDo(Object message) {       System.out.println(message+":"+name);            }}

然后再定义下雨的老天爷(被观察者:具备下雨行为),因为老天爷只有一个,所以我这里定义了单利模式(不是单利也行)

package com.lxz;import java.util.ArrayList;import java.util.List;/** * 描述: * 作者:Linxz * 邮箱:lin_xiao_zhang@163.com * 时间: 2017年4月14日 上午11:27:33 * 版本:1.0 */public class God implements Observerable{    private static God instance;    /**收集全部的观察者*/    private static List<Observer> observers=new ArrayList<>();    private God(){}    public static God newInstance(){       if(instance==null){           instance=new God();       }       return instance;    }    /**谁在观察我*/    @Override    public void attach(Observer observer) {        observers.add(observer);        }    /**谁不再观察我了*/    @Override    public void detach(Observer observer) {        observers.remove(observer);    }    /**我开始下雨了*/    @Override    public void notifyObservers(Object message) {        for(Observer observer:observers){            observer.farmerDo(message);        }    }}

到此已经将农民跟老天爷实体定义好了,那现在老天爷就准备下雨了:

package com.lxz;/** * 描述: * 作者:Linxz * 邮箱:lin_xiao_zhang@163.com * 时间: 2017年4月14日 上午11:36:05 * 版本:1.0 */public class ObserverExeceute {    public static void main(String[] args) {        /**老天爷*/        Observerable god=God.newInstance();        /**农民伯伯*/        Observer farmerA=new Farmer();        farmerA.setName("农民伯伯马上种瓜");        god.attach(farmerA);        /**农民阿姨*/        Observer farmerB=new Farmer();        farmerB.setName("农民阿姨马上种豆");        god.attach(farmerB);        /**老天爷下雨了*/        god.notifyObservers("下雨了");    }}

这里写图片描述

从结果可以看到,老天爷一下雨,农民伯伯就去种瓜、农民阿姨就去种豆了。从结果也能很好地看到观察者模式可以很好地进行解耦,农民伯伯、农民阿姨都对老天爷进行了观察,下雨了时候他们的行为却不一样。也就是说,老天爷只管通知观察者我下雨了,至于具体的操作就由他们自由去决定,而观察者跟观察者之间可以没有一丁点关系。在程序中,有时候一个类的数据改变了,可能会触发好几个类的数据改变,这时候使用观察者模式就能很好地解决问题。

那么在Android开发的过程中有哪些情况可以使用观察者模式呢?举个简单的例子。每个APP应用程序都会有登录注册逻辑。比如注册要涉及:填写手机号(第一个页面)—>接收验证码(第二个页面)–>设置密码(第三个页面)—>注册(APP主页),进入APP主页的时候就应该把用户的注册登录页面销毁了。这种逻辑很多人会使用带值跳转,页面销毁时会往上一个页面返回一个标识要销毁页面的值,在onActivityForResult中进行页面销毁,如下:
Register1Activity:
这里写图片描述

Register2Activity:
这里写图片描述

Register3Activity
这里写图片描述

这样就能把注册流程的全部页面给销毁了,很多人都是这么干的。有的人也会使用广播,注册成功之后发送一个广播,注册流程的页面接收到这个广播之后就销毁页面。

现在认识了观察者模式可以使用观察者模式实现,注册流程的Activity都实现观察者Observer,注册成功之后被观察者通知观察者注册成功,销毁页面(和上面农民的故事一个原理)。
首先定义观察者接口:

package linxz.com.streamlet.interfaces;/** * 功能描述: * 作者:Linxz * E-mail:lin_xiao_zhang@13.com * 版本信息:V1.0.0 * 时间:2017年04月14日  9:39. **/public interface Observer {    /**标识是哪个实体类(可以不要这个方法)*/    public void setName(String name);    /**该实体类需要更新数据(不需要传递数据的情况下此方法可以为无参)*/    public void updateDate(Object object);}

被观察者接口:

package linxz.com.streamlet.interfaces;/** * 功能描述: * 作者:Linxz * E-mail:lin_xiao_zhang@13.com * 版本信息:V1.0.0 * 时间:2017年04月14日  9:41. **/public interface Observable {    /**订阅*/    public void attach(Observer observer);    /**取消订阅*/    public void detach(Observer observer);    /**通知观察者更新数据*/    public void notifyObservers(Object object);}

定义一个类专用来执行观察、取消观察、通知更新:

package linxz.com.streamlet.interfaces;import java.util.ArrayList;import java.util.List;/** * 功能描述: * 作者:Linxz * E-mail:lin_xiao_zhang@13.com * 版本信息:V1.0.0 * 时间:2017年04月14日  10:14. **/public class ObserverExecute implements Observable{    private static ObserverExecute instance;    /**搜集全部的观察者*/    private static List<Observer> observers=new ArrayList<>();    private ObserverExecute(){}    public static ObserverExecute newInstance(){        if (instance==null){            instance=new ObserverExecute();        }        return instance;    }    /**订阅*/    @Override    public void attach(Observer observer) {        observers.add(observer);    }    /**取消订阅*/    @Override    public void detach(Observer observer) {        observers.remove(observer);    }    /**通知更新数据或者销毁页面*/    @Override    public void notifyObservers(Object object) {        for (Observer observer:observers){            observer.updateDate(object);        }    }}

注册流程的Activity都实现观察者接口,并执行订阅,观察注册成功行为:
这里写图片描述

实现的接口的方法中对页面进行销毁:
这里写图片描述

当然Activity销毁的时候要执行取消订阅
这里写图片描述

注册流程的Activity都这么操作成为一个观察者。

注册成功之后对通知全部的观察者注册成功:
这里写图片描述

就这样,注册流程的页面也会跟着销毁了。这种流程其实归根结底还是把注册流程的Activity存储起来,注册成功了就进行销毁。

观察者模式在Android中可以运用在很多逻辑里面,比如购买不一样的商品,支付的时候选择其中一款商品进行支付,支付成功的时候需要更新购物车。还有很多需要及时更新数据的时候也可以使用观察者模式。

1 0