您的位置:首页 > 其它

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

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

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

java提供Obeservable类和Observer接口。

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

/**
*被观察者
*@authorsoyoungboy
*
*/
publicclassHouseextendsObservable{
//房价
privatefloatprice;

publicHouse(floatprice){
this.price=price;
}

publicfloatgetPrice(){
returnprice;
}

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

@Override
publicStringtoString(){
return"House[price="+price+"]";
}

}


/**
*房价观察者
*@authorsoyoungboy
*
*/
publicclassHouseObserverimplementsObserver{
//购房者名称
privateStringname;

publicHouseObserver(Stringname){
this.name=name;
}
@Override
publicvoidupdate(Observableo,Objectarg){
if(arginstanceofFloat){
System.out.println("name观察到房价变化为:"+((Float)arg).floatValue());
}
}
}


publicclassTest{

publicstaticvoidmain(String[]args){
Househouse=newHouse(10000);
HouseObserverhouseObserver=newHouseObserver("购房者A");
HouseObserverhouseObserver1=newHouseObserver("购房者B");
HouseObserverhouseObserver2=newHouseObserver("购房者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()--添加观察者,删除观察者对象



publicclassTANetworkStateReceiverextendsBroadcastReceiver{
privatestaticfinalStringTAG="TANetworkStateReceiver";

privatestaticBooleannetworkAvailable=false;

privatestaticnetTypenetType;

privatestaticArrayList<TANetChangeObserver>netChangeObserverArrayList=
newArrayList<TANetChangeObserver>();

privatefinalstaticStringANDROID_NET_CHANGE_ACTION=
"android.net.conn.CONNECTIVITY_CHANGE";

publicfinalstaticStringTA_ANDROID_NET_CHANGE_ACTION=
"ta.android.net.conn.CONNECTIVITY_CHANGE";

privatestaticBroadcastReceiverreceiver;

privatestaticBroadcastReceivergetReceiver(){
if(receiver==null){
receiver=newTANetworkStateReceiver();
}
returnreceiver;
}

@Override
publicvoidonReceive(Contextcontext,Intentintent){
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();
}
}

/**
*注册网络状态广播
*
*@parammContext
*/
publicstaticvoidregisterNetworkStateReceiver(ContextmContext){
IntentFilterfilter=newIntentFilter();
filter.addAction(TA_ANDROID_NET_CHANGE_ACTION);
filter.addAction(ANDROID_NET_CHANGE_ACTION);
mContext.getApplicationContext()
.registerReceiver(getReceiver(),filter);
}

/**
*检查网络状态
*
*@parammContext
*/
publicstaticvoidcheckNetworkState(ContextmContext){
Intentintent=newIntent();
intent.setAction(TA_ANDROID_NET_CHANGE_ACTION);
mContext.sendBroadcast(intent);
}

/**
*注销网络状态广播
*
*@parammContext
*/
publicstaticvoidunRegisterNetworkStateReceiver(ContextmContext){
if(receiver!=null){
try{
mContext.getApplicationContext().unregisterReceiver(receiver);
}catch(Exceptione){
//TODO:handleexception
//TALogger.d("TANetworkStateReceiver",e.getMessage());
Logger.i(TAG,e.getMessage());
}
}

}

/**
*获取当前网络状态,true为网络连接成功,否则网络连接失败
*
*@return
*/
publicstaticBooleanisNetworkAvailable(){
returnnetworkAvailable;
}

publicstaticnetTypegetAPNType(){
returnnetType;
}

privatevoidnotifyObserver(){

for(inti=0;i<netChangeObserverArrayList.size();i++){
TANetChangeObserverobserver=netChangeObserverArrayList.get(i);
if(observer!=null){
if(isNetworkAvailable()){
/*observer.onConnect(netType);*/
observer.onConnect(netType);
}else{
observer.onDisConnect();
}
}
}

}

/**
*注册网络连接观察者
*
*@paramobserverKeyobserverKey
*/
publicstaticvoidregisterObserver(TANetChangeObserverobserver){
if(netChangeObserverArrayList==null){
netChangeObserverArrayList=newArrayList<TANetChangeObserver>();
}
netChangeObserverArrayList.add(observer);
}

/**
*注销网络连接观察者
*
*@paramresIDobserverKey
*/
publicstaticvoidremoveRegisterObserver(TANetChangeObserverobserver){
if(netChangeObserverArrayList!=null){
netChangeObserverArrayList.remove(observer);
}
}

}


检测网络改变的观察者:

publicclassTANetChangeObserver{
/**
*网络连接连接时调用
*/
publicvoidonConnect(netTypetype){

}

/**
*当前没有网络连接
*/
publicvoidonDisConnect(){

}
}


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

TANetworkStateReceiver.registerObserver(newTANetChangeObserver()
{
@Override
publicvoidonConnect(netTypetype)
{
//TODOAuto-generatedmethodstub
super.onConnect(type);
Toast.makeText(TestActivity.this,"onConnect",
Toast.LENGTH_SHORT).show();
}

@Override
publicvoidonDisConnect()
{
//TODOAuto-generatedmethodstub
super.onDisConnect();
Toast.makeText(TestActivity.this,"onDisConnect",
Toast.LENGTH_SHORT).show();
}
});


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

2015年12月20日20:55:37

观察者模式在android源码中的使用(读《androidsourcedesignpatternanalysis&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将广播分发给订阅对象。

观察者模式的适用场景就是一个类发生变化,需要将消息传递到相关很多类的时候。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: