Android设计模式之观察者模式


 

场景:一个android程序中,存在好几个activity和几个fragment,当一个地方发生改变时,其他地方跟着改变。

看到这个问题,我们通常会想到Handler的sendMessage方式发送消息,在需要的地方接收消息,如果需要在N个activity中改变,就需要接收N次,这种实现就比较繁琐,不适合使用;然后我们还会想到发送广播方式来通知,

 自定义一个广播,然后在通知的地方接收广播,这种方式需要开发者先接收广播,在结束的地方取消接听,这种方法同样不适合。

      以上两种方式都属于发布----订阅模式,只是在上述场景中使用起来比较繁琐。Android中还封装了一个类,叫做Observable;这个类是被观察者,有了被观察者,那么一定存在一个观察者,所以有一个接口Observer,观察者类只要实现这个接口,就可以观察到被观察者。让我们通过一个简单的示例来了解一下。

首先,创建一个观察者类:

import android.util.Log;
import
java.util.Observable;
import
java.util.Observer;
/**
 * coder
 *
<p>
 
* Created by czx on2017/1/11.
 */
public class Coder implements Observer {
   
private staticfinal String TAG = "Coder.class";
    private
String name;
    public
Coder(String name) {
       
this.name = name;
   
}
   
@Override
   
public void update(Observableobservable, Object data) {
        Log.
e(TAG, toString() + "观察到新的消息:" + data);
   
}
   
@Override
   
public String toString() {
        
return "观察者" + name;
   
}
}

这个类实现了Observer这个接口,重写update方法,当被观察者发布新的消息时,观察者就可以通过update方法接受到这个消息。

接下来,就定义被观察者类:

importjava.util.Observable;
/**
 * DevTechFrontier
 * Created by czx on 2017/1/11.
 */
public class DevTechFrontier extends Observable {
    public void postNewPublication(String news) {
        setChanged();
        notifyObservers(news);
    }
}

 这个类代码很少,可以看到它是继承了Observable这个类,我们给他定义一个方法,叫做postNewPublication(String news),这个方法就是用来发布消息的,他里面使用了父类的两个方法:setChanged()、notifyObservers(news);查看源码,发现:

/**
 * Sets the changed flag for this {@code Observable}. After calling
 * {@code setChanged()}, {@code hasChanged()} will return {@code true}.
 */
protected void setChanged() {
    changed = true;
}

     这个方法就是用来确定要发消息,发送消息的时候判断changed这个变量,如果为true就发布,具体情况可以查看源码:


/**
 * Returns the changed flag for this {@code Observable}.
 *
 * @return {@code true} when the changed flag for this {@code Observable} is
 *         set, {@code false} otherwise.
 */
public boolean hasChanged() {
    return changed;
}

/**
 * If {@code hasChanged()} returns {@code true}, calls the {@code update()}
 * method for every observer in the list of observers using null as the
 * argument. Afterwards, calls {@code clearChanged()}.
 * <p>
 * Equivalent to calling {@code notifyObservers(null)}.
 */
public void notifyObservers() {
    notifyObservers(null);
}
/**
 * If {@code hasChanged()} returns {@code true}, calls the {@code update()}
 * method for every Observer in the list of observers using the specified
 * argument. Afterwards calls {@code clearChanged()}.
 *
 * @param data
 *            the argument passed to {@code update()}.
 */
@SuppressWarnings("unchecked")
public void notifyObservers(Object data) {
    int size = 0;
    Observer[] arrays = null;
    synchronized (this) {
        if (hasChanged()) {
            clearChanged();
            size = observers.size();
            arrays = new Observer[size];
            observers.toArray(arrays);
        }
    }
    if (arrays != null) {
        for (Observer observer : arrays) {
            observer.update(this, data);
        }
    }
}

有上面的源码可以看出,DevTechFrontier中,调用了父类的notifyObservers()方法发布了消息。

接下来我们在看看具体的测试调用:

DevTechFrontier devTechFrontier = new DevTechFrontier();
Coder coder = new Coder("coder");
Coder coder1 = new Coder("coder1");
Coder coder2 = new Coder("coder2");
Coder coder3 = new Coder("coder3");
devTechFrontier.addObserver(coder);
devTechFrontier.addObserver(coder1);
devTechFrontier.addObserver(coder2);
devTechFrontier.addObserver(coder3);
devTechFrontier.postNewPublication("My first new : hello word!");

使用方法也比较简单,首先实例化被观察者和观察者,然后将观察者add到被观察者的观察者列表中,最后就可以发布消息了。

使用效果:

01-1211:20:53.392 12047-12047/com.cn.czx.observertest E/Coder.class: 观察者coder观察到新的消息:Myfirst new : hello word!

01-1211:20:53.392 12047-12047/com.cn.czx.observertest E/Coder.class: 观察者coder1观察到新的消息:Myfirst new : hello word!

01-1211:20:53.392 12047-12047/com.cn.czx.observertest E/Coder.class: 观察者coder2观察到新的消息:Myfirst new : hello word!

01-1211:20:53.392 12047-12047/com.cn.czx.observertest E/Coder.class: 观察者coder3观察到新的消息:Myfirst new : hello word!

 

在此,一个简单的观察者模式就结束了。

总结一下优缺点(别人总结的>_<):

优点:

1、观察者和被观察者之间抽象耦合,应对业务变化

2、增强系统灵活性、可扩展性

缺点:

       在使用观察者模式时,需要考虑开发效率和运行效率问题,java的消息通知默认顺序执行,当程序中包含了一个被观察者和多个观察者的时候,如果一个观察者发生卡顿,就会影响执行效率,这种情况就考虑使用异步的方法。

在实际开发中,我们可以根据具体情况确定使用哪种方式。

在这里介绍一个比较方便的开源库,Greenaobot的EvenBus,使用也是非常简单,可以自行查找使用方法。而且这个库是异步执行。

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值