浅谈Android移动架构(七)行为模式之观察者模式

定义:

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

简单分析:

《浅谈Android移动架构(七)行为模式之观察者模式》 观察者模式.png

实例分析:

观察者模式应该包含以下角色:
1抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
2.具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
3.抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
4.具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

代码简单实现:

1.抽象主题:

/**
 * 抽象被观察者
 * @author Administrator
 *
 */
public class AbstractSubject {
    /**
     * 保存注册观察者对象
     */
    private List<Observer> list=new ArrayList<>();
    
    /**
     * 添加观察者
     * @param observer
     */
    public void attach(Observer observer)
    {
        list.add(observer);
        
    }
    /**
     * 删除观察者
     * @param observer
     */
    public void detach(Observer observer)
    {
        list.remove(observer);
    }
    /**
     * 更新所有注册的观察者
     * @param content
     */
    public  void notifyObservers(String content)
    {
        for(Observer observer:list)
        {
            observer.update(content);
        }
    }
}

2.具体主题

public class ConcreteSubject extends AbstractSubject {
    
}

3.抽象观察者(Observer)角色

public interface Observer {
    /**
     * 更新接口
     * @param state
     */
    public void update(String state);

}

4.具体观察者

public class ConcreteObserver  implements Observer{
    private String name;
    public ConcreteObserver(String name) {
        this.name = name;
    }   
    public void update(String content) {
        System.out.println(name+":   "+content);
    }
}

5.执行

public class Client {
        public static void main(String[] args) {
            ConcreteSubject subject=new ConcreteSubject();
            Observer observer1=new ConcreteObserver("观察者一");
            Observer observer2=new ConcreteObserver("观察者二");
            Observer observer3=new ConcreteObserver("观察者三");
            subject.attach(observer1);
            subject.attach(observer2);
            subject.attach(observer3);
            subject.notifyObservers("被观察者 发生了变化");
        }
}
Android源码:

在Android中也提供了一个类Observable用于观察者模式,下面看看Observable 的源码

package android.database;  
  
import java.util.ArrayList;  
  
/** 
 * Provides methods for (un)registering arbitrary observers in an ArrayList. 
 */  
public abstract class Observable<T> {  
    /** 
     * The list of observers.  An observer can be in the list at most 
     * once and will never be null. 
     */  
    protected final ArrayList<T> mObservers = new ArrayList<T>();  
  
    /** 
     * Adds an observer to the list. The observer cannot be null and it must not already 
     * be registered. 
     * @param observer the observer to register 
     * @throws IllegalArgumentException the observer is null 
     * @throws IllegalStateException the observer is already registered 
     */  
    public void registerObserver(T observer) {  
        if (observer == null) {  
            throw new IllegalArgumentException("The observer is null.");  
        }  
        synchronized(mObservers) {  
            if (mObservers.contains(observer)) {  
                throw new IllegalStateException("Observer " + observer + " is already registered.");  
            }  
            mObservers.add(observer);  
        }  
    }  
  
    /** 
     * Removes a previously registered observer. The observer must not be null and it 
     * must already have been registered. 
     * @param observer the observer to unregister 
     * @throws IllegalArgumentException the observer is null 
     * @throws IllegalStateException the observer is not yet registered 
     */  
    public void unregisterObserver(T observer) {  
        if (observer == null) {  
            throw new IllegalArgumentException("The observer is null.");  
        }  
        synchronized(mObservers) {  
            int index = mObservers.indexOf(observer);  
            if (index == -1) {  
                throw new IllegalStateException("Observer " + observer + " was not registered.");  
            }  
            mObservers.remove(index);  
        }  
    }  
      
    /** 
     * Remove all registered observer 
     */  
    public void unregisterAll() {  
        synchronized(mObservers) {  
            mObservers.clear();  
        }          
    }  
}  

在Android中最常用的应用:
在ListView中Adapter中favoritesAdapter.registerDataSetObserver(mDataSetObserver);;数据改变之后会自动调用:mDataSetObserver里面的方法;如:

DataSetObserver mDataSetObserver = new DataSetObserver() {  
        @Override  
        public void onChanged() {  
            if (favoritesAdapter.getCount() <= 0) {  
                showNoDeviceHint();  
            } else {  
                hiddenNoDeviceHint();  
            }  
            loadingImageButton.setVisibility(View.GONE);  
            super.onChanged();  
        }  
        @Override  
        public void onInvalidated() {  
            super.onInvalidated();  
        }  
    };  
总结:观察者模式何时适用?

1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中可以使他们各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而不知道具体由多少对象有待改变。
3.当一个对象必须通知其他对象,而它又不能假定其他对象是谁,换言之,你不希望这些对象是紧密耦合的。让耦合的双方都依赖于抽象,而不是依赖于具体。

其他模式,会继续更新……

    原文作者:简飘飘
    原文地址: https://www.jianshu.com/p/15969fea9719
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞