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

刚开始学习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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值