zoukankan      html  css  js  c++  java
  • 设计模式--观察者设计模式

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

    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将广播分发给订阅对象。

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

     

  • 相关阅读:
    selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
    ERROR: virtualenvwrapper could not find virtualenv in your path
    VM中的Centos 7配置静态IP
    CentOS7 安装JumpServer
    ERROR 1130 (HY000): Host 'test177' is not allowed to connect to this MySQL server
    获取到一张表中指定字段重复的数量
    Windows7设置局域网文件共享
    vmware虚拟机安装Windows 7后虚拟机自动挂起
    关于PHP版本比较函数version_compare的问题
    关于数据表中一对多、多对一关系的设计
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/4744805.html
Copyright © 2011-2022 走看看