设计模式~观察者-[Android_YangKe]

观察者模式:
yangke.png

观察者模式属于行为型模式中的一员, 是开发中很常用的设计模式之一, 它的优点是当一个对象的属性发生变化时会通知所有对它进行注册的观察者.

例: 拍卖会上的物品是被观察者, 其他所有的竞价者都是观察者, 当被拍卖的物品价格变动时所有的竞价者(观察者)都会得到通知, 被拍卖物品与竞价者之间的关系应用的就是观察者模式.

为什么要使用此模式呢 ?

  1. 一对多的关系, 即当被观察者的属性发生变化时, 所有对此注册的观察者都会得到通知.
  2. 当我们需要对被观察者进行监测时只需手动添加一个观察者, 被观察者只需对外提供一个通知的函数.

下面说一个android中常见的观察者模式:

EditText是一个输入框控件, 它有一个addTextChangedListener函数相信大家都比较清楚, 今天我们拔下源码:

  /**
 * Adds a TextWatcher to the list of those whose methods are called
 * whenever this TextView's text changes.
 * 

* In 1.0, the {@link TextWatcher#afterTextChanged} method was erroneously * not called after {@link #setText} calls. Now, doing {@link #setText} * if there are any text changed listeners forces the buffer type to * Editable if it would not otherwise be and does call this method. */ public void addTextChangedListener(TextWatcher watcher) { if (mListeners == null) { mListeners = new ArrayList(); } mListeners.add(watcher); }

以上源码进行大致解析:

  1. 此函数作用: 为EditText添加一个观察者.

  2. 什么时候调用? 当TextView文本发生变化时(EditText是TextView的子类).

  3. 观察者添加到哪里? ArrayList.

通过上面源码我们可以得到这样一个核心内容: 观察者模式内部是使用一个集合对观察者进行管理的. ok, 有添加操作就会有移除操作, 我们继续看:

/**
 * Removes the specified TextWatcher from the list of those whose
 * methods are called
 * whenever this TextView's text changes.
 */
public void removeTextChangedListener(TextWatcher watcher) {
    if (mListeners != null) {
        int i = mListeners.indexOf(watcher);

        if (i >= 0) {
            mListeners.remove(i);
        }
    }
}

代码挺简单, 首先判断了下集合是否为空, 当mListeners(观察者)不为空的情况下, 从集合中找到指定的观察者进行移除操作. 以上就是观察者的核心, 下面我们写个完整例子.

1. Subject
/**
* @author yangke 一个主题,用于管理观察者
*/
public interface ISubject {
void addObs(IObserver obs);
void removeObs(IObserver obs);
void notify(String msg);
}
2. IObserver
/**
* @author yangke 观察者
*/
public interface IObserver {
void update(String value);
}
3. Obs1
public class Obs1 implements IObserver{
@Override
public void update(String value) {
    System.out.println("我是学生:"+getClass().getName()+value); 
}
}
4. Obs2
public class Obs2 implements IObserver {
@Override
public void update(String value) {
    System.out.println("我是学生:"+getClass().getName()+value);
}
}
5. Subjected
/**
 * @author yangke 具体被观察者用于管理观察者
 */
public class Subjected implements ISubject {
private List list = new ArrayList<>();

/**
 * 添加观察者
 */
public void addObs(IObserver obs) {
    if (!list.contains(obs)) {
        list.add(obs);
    }
}

/**
 * 移除观察者
 */
public void removeObs(IObserver obs) {
    if (list.contains(obs)) {
        list.remove(obs);
    }
}

/**
 * 通知具体的观察者
 */
public void notify(String msg) {
    for (IObserver obs : list) {
        obs.update(msg);
    }
}
6. Test
public class Test {
public static void main(String[] args) {
    Obs2 ob1 = new Obs2();
    Obs1 s2 = new Obs1();
    Subjected s = new Subjected();
    
    s.addObs(ob1);
    s.addObs(s2);
    s.notify("---------");
}
}

OK代码到这里就结束了, 下面我们看下打印结果:

yangke.png

总结:

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:当一个对象的状态变化后需要通知多个对象时.
关键代码:使用集合对观察者进行管理.
优点:

  1. 一对多的关系, 即当被观察者的属性发生变化时, 所有对此注册的观察者都会得到通知.
  2. 当我们需要对被观察者进行监测时只需手动添加一个观察者, 被观察者只需对外提供一个通知的函数.

缺点:

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费一些时间.
  2. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

单例-->http://www.jianshu.com/p/137593180979
模板--> http://www.jianshu.com/p/2f1964f98e44

喜欢有帮助的话: 双击、评论、转发,动一动你的小手让更多的人知道!关注 帅比-杨

你可能感兴趣的:(设计模式~观察者-[Android_YangKe])