您的位置:首页 > 其它

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

2017-07-03 15:17 239 查看
刚开始学习Java的就接触观察者模式了,但是总是不太能理解这种模式或者理解的一点不深刻,特别容易忘记。最近搞Android总是遇到RxJava,RxAndroid,毕竟RxJava+RxAndroid+okHttp太火了。为了学习这种框架就得重新搞一下Java的观察者模式了。接下来我们通过一个故事来了解一下观察者模式:

话说桃花源的农民都很聪明,耕种的时候都会在老天下雨的时候开始耕种,这样种出来的庄稼会有更好的收成。所以种瓜的农民伯伯、种豆的农民阿姨天天都在观察着老天爷。(老天爷:被观察者)老天爷一下雨,农民伯伯就马上种瓜、农民阿姨马上种豆。(注意:农民伯伯、农民阿姨两人可能基本不认识,两者一点关系都没有)。

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

package com.zyb;
/**
* 描述:观察者(农民)
* 作者:zyb
* 时间: 2017年4月14日 上午11:05:32
* 版本:1.0
*/
public interface Observer {

/**标记当前观察者是谁*/
public void setName(String name);

/**老天下雨的时候农民的行为*/
public void farmerDo(Object message);

}


被观察者(老天爷)

package com.zyb;
/**
* 描述:被观察者(老天爷)
* 作者:zyb
* 时间: 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.zyb;
/**
* 描述:
* 作者:zyb
* 时间: 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.zyb;
/**
* 描述:
* 作者:zyb
* 时间: 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 com.zyb.streamlet.interfaces;
/**
* 功能描述:
* 作者:zyb
* 版本信息:V1.0.0
* 时间:2017年04月14日  9:39.
**/
public interface Observer {

/**标识是哪个实体类(可以不要这个方法)*/
public void setName(String name);

/**该实体类需要更新数据(不需要传递数据的情况下此方法可以为无参)*/
public void updateDate(Object object);
}


被观察者接口:

package com.zyb.streamlet.interfaces;
/**
* 功能描述:
* 作者:zyb
* 版本信息: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 com.zyb.streamlet.interfaces;
import java.util.ArrayList;
import java.util.List;
/**
* 功能描述:
* 作者:zyb
* 版本信息: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中可以运用在很多逻辑里面,比如购买不一样的商品,支付的时候选择其中一款商品进行支付,支付成功的时候需要更新购物车。还有很多需要及时更新数据的时候也可以使用观察者模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  观察者模式