设计模式--观察者设计模式

定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

java提供Obeservable类和Observer接口。

比如购房,购房者是观察者,而房价是被观察者,房价的变化是被观察者所关注的。

/**
 * 被观察者
 * @author soyoungboy
 *
 */
public class House extends Observable {
    //房价
    private float price;

    public House(float price) {
        this.price = price;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        //设置变化点
        super.setChanged();
        //通知观察者,价格发生变化
        super.notifyObservers(price);
        this.price = price;
    }

    @Override
    public String toString() {
        return "House [price=" + price + "]";
    }

}

 

/**
 * 房价观察者
 * @author soyoungboy
 *
 */
public class HouseObserver implements Observer {
    //购房者名称
    private String name;

    public HouseObserver(String name) {
        this.name = name;
    }
    @Override
    public void update(Observable o, Object arg) {
        if (arg instanceof Float) {
            System.out.println("name 观察到房价变化为:"+((Float)arg).floatValue());
        }
    }
}
public class Test {

    public static void main(String[] args) {
        House house = new House(10000);
        HouseObserver houseObserver = new HouseObserver("购房者A");
        HouseObserver houseObserver1 = new HouseObserver("购房者B");
        HouseObserver houseObserver2 = new HouseObserver("购房者C");
        //添加房价的监听者
        house.addObserver(houseObserver);
        house.addObserver(houseObserver1);
        house.addObserver(houseObserver1);
        System.out.println(house.toString());
        house.setPrice(20000);
        System.out.println(house.toString());
        house.setPrice(30000);
        System.out.println(house.toString());
    }

}

结果为:

House [price=10000.0]
name 观察到房价变化为:20000.0
name 观察到房价变化为:20000.0
House [price=20000.0]
name 观察到房价变化为:30000.0
name 观察到房价变化为:30000.0
House [price=30000.0]

 观察者模式在android编码过程中的使用

 比如网络状态的变化,每个activity都有链接网络的操作,当网络状态发生变化的使用,应该通过通知所有涉及到网络操作的activity网络状态的变化,并且能够根据网络状态不同进行不同的处理,比如2G,3G网络下,不进行网络图片的加载,而在wifi网络的情况下进行加载:下面是thinkandroid里面实现网络状态监听的观察者模式的使用:

 

TANetChangeObserver -- 观察者
TANetworkStateReceiver.registerObserver()--为添加新的观察者
notifyObserver() -- 为通知所有的观察者网络状态的变化
registerObserver(),removeRegisterObserver ()--添加观察者,删除观察者对象
 
public class TANetworkStateReceiver extends BroadcastReceiver {
    private static final String TAG = "TANetworkStateReceiver";
    
    private static Boolean networkAvailable = false;
    
    private static netType netType;
    
    private static ArrayList<TANetChangeObserver> netChangeObserverArrayList =
        new ArrayList<TANetChangeObserver>();
    
    private final static String ANDROID_NET_CHANGE_ACTION =
        "android.net.conn.CONNECTIVITY_CHANGE";
    
    public final static String TA_ANDROID_NET_CHANGE_ACTION =
        "ta.android.net.conn.CONNECTIVITY_CHANGE";
    
    private static BroadcastReceiver receiver;
    
    private static BroadcastReceiver getReceiver() {
        if (receiver == null) {
            receiver = new TANetworkStateReceiver();
        }
        return receiver;
    }
    
    @Override
    public void onReceive(Context context, Intent intent) {
        receiver = TANetworkStateReceiver.this;
        if (intent.getAction().equalsIgnoreCase(ANDROID_NET_CHANGE_ACTION)
            || intent.getAction()
                .equalsIgnoreCase(TA_ANDROID_NET_CHANGE_ACTION)) {
            Logger.i(TAG, "网络状态改变.");
            if (!TANetWorkUtil.isNetworkAvailable(context)) {
                Logger.i(TAG, "没有网络连接.");
                ToastUtil.toasts(context, "网络断开,请检查网络");
                networkAvailable = false;
            } else {
                Logger.i(TAG, "网络连接成功.");
                ToastUtil.toastL(context, "网络连接成功");
                netType = TANetWorkUtil.getAPNType(context);
                networkAvailable = true;
            }
            notifyObserver();
        }
    }
    
    /**
     * 注册网络状态广播
     * 
     * @param mContext
     */
    public static void registerNetworkStateReceiver(Context mContext) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(TA_ANDROID_NET_CHANGE_ACTION);
        filter.addAction(ANDROID_NET_CHANGE_ACTION);
        mContext.getApplicationContext()
            .registerReceiver(getReceiver(), filter);
    }
    
    /**
     * 检查网络状态
     * 
     * @param mContext
     */
    public static void checkNetworkState(Context mContext) {
        Intent intent = new Intent();
        intent.setAction(TA_ANDROID_NET_CHANGE_ACTION);
        mContext.sendBroadcast(intent);
    }
    
    /**
     * 注销网络状态广播
     * 
     * @param mContext
     */
    public static void unRegisterNetworkStateReceiver(Context mContext) {
        if (receiver != null) {
            try {
                mContext.getApplicationContext().unregisterReceiver(receiver);
            } catch (Exception e) {
                // TODO: handle exception
                // TALogger.d("TANetworkStateReceiver", e.getMessage());
                Logger.i(TAG, e.getMessage());
            }
        }
        
    }
    
    /**
     * 获取当前网络状态,true为网络连接成功,否则网络连接失败
     * 
     * @return
     */
    public static Boolean isNetworkAvailable() {
        return networkAvailable;
    }
    
    public static netType getAPNType() {
        return netType;
    }
    
    private void notifyObserver() {
        
        for (int i = 0; i < netChangeObserverArrayList.size(); i++) {
            TANetChangeObserver observer = netChangeObserverArrayList.get(i);
            if (observer != null) {
                if (isNetworkAvailable()) {
                    /* observer.onConnect(netType); */
                    observer.onConnect(netType);
                } else {
                    observer.onDisConnect();
                }
            }
        }
        
    }
    
    /**
     * 注册网络连接观察者
     * 
     * @param observerKey observerKey
     */
    public static void registerObserver(TANetChangeObserver observer) {
        if (netChangeObserverArrayList == null) {
            netChangeObserverArrayList = new ArrayList<TANetChangeObserver>();
        }
        netChangeObserverArrayList.add(observer);
    }
    
    /**
     * 注销网络连接观察者
     * 
     * @param resID observerKey
     */
    public static void removeRegisterObserver(TANetChangeObserver observer) {
        if (netChangeObserverArrayList != null) {
            netChangeObserverArrayList.remove(observer);
        }
    }
    
}

 

检测网络改变的观察者:

public class TANetChangeObserver {
    /**
     * 网络连接连接时调用
     */
    public void onConnect(netType type) {
        
    }
    
    /**
     * 当前没有网络连接
     */
    public void onDisConnect() {
        
    }
}

如下为程序中的使用方式:

 1 TANetworkStateReceiver.registerObserver(new TANetChangeObserver()
 2         {
 3             @Override
 4             public void onConnect(netType type)
 5             {
 6                 // TODO Auto-generated method stub
 7                 super.onConnect(type);
 8                 Toast.makeText(TestActivity.this, "onConnect",
 9                         Toast.LENGTH_SHORT).show();
10             }
11 
12             @Override
13             public void onDisConnect()
14             {
15                 // TODO Auto-generated method stub
16                 super.onDisConnect();
17                 Toast.makeText(TestActivity.this, "onDisConnect",
18                         Toast.LENGTH_SHORT).show();
19             }
20         });

 最后这段代码其实是可以放到BaseActivity中对所有Activity界面进行控制的,每个页面中的网络状态其实都可以通过这种方式进行统一管理,有添加观察者,也要在生命周期里面及时删除观察者。


2015年12月20日20:55:37

观察者模式在android源码中的使用(读《android source design pattern analysis & pratice》)

BaseAdapter中使用了观察者设计模式

BaseAdapter里面有注册观察者和解除观察者的操作以及通知所有观察者的notifyDateSetChange()代码.

部分分析的博客:http://www.cnblogs.com/izhanjun/p/4183788.html

Mr.simple的博客:http://blog.csdn.net/bboyfeiyu/article/details/44040533

还有就是BroadCastReceiver也是观察者模式

通过map存储BroadcastReceiver,key封装广播的信息类,当发布广播通过AMS到这个map中查询注册了这个广播的IntentFilter的BroadCastReveiver,然后通过ReceiverSpipather将广播分发给订阅对象。

 观察者模式的适用场景就是一个类发生变化,需要将消息传递到相关很多类的时候。

 

原文地址:https://www.cnblogs.com/androidsuperman/p/4744805.html