我之前一直有听着观察者模式,但是一直没怎么实际运用过,后来在做项目的过程中,在一些前辈的指导下,学会了运用观察者模式到实际的项目当中,其实观察者模式对于我们项目的帮助还是蛮大的,自动通知各个观察者当前状态的变化,是一个十分有用的设计模式。
这次运用的在登陆过程中的观察者模式,当用户已经注册过应用,就直接进入,没有注册,就注册保存,并且当用于退出时,做相应的修改,当用户信息修改时,也要做相应得通知。实际上就是当用户的信息变更时,系统能够通知各个监听用户状态的观察者,从而做出相应的行为。
首先是观察者模式的基本方法:
1.创建一个观察者类,采用弱引用的方法,不容易导致内存泄露,不清楚弱引用的可以看看这篇 http://blog.youkuaiyun.com/matrix_xu/article/details/8424038:
public class DataObserver
{
private WeakReference<Object> mReferenceObserver = null;
/**
*
*/
public DataObserver(Object observer)
{
mReferenceObserver = new WeakReference<Object>(observer);
}
public Object getObserver()
{
if (mReferenceObserver != null)
{
return mReferenceObserver.get();
}
return null;
}
}
2.创建一个观察者池,说白了就是用对观察者的增删查改,设置key值为观察者的唯一标识符。
public class DataObserverPool
{
// private static final String TAG = "LogicManagerObserverPool";
protected Map<String, List<DataObserver>> mObserverMap;
/**
*
*/
public DataObserverPool()
{
mObserverMap = new HashMap<String, List<DataObserver>>();
}
/**
* 添加监听者
* @param key
* @param observer
*/
public void addObserver(String key, DataObserver observer)
{
List<DataObserver> observerList = getObservers(key);
if (observerList == null)
{
observerList = new ArrayList<DataObserver>();
mObserverMap.put(key, observerList);
}
observerList.add(observer);
}
/**
* 根据key删除监听
* @param key
* @param observer
*/
public void removeObserver(String key, DataObserver observer)
{
List<DataObserver> observerList = getObservers(key);
if (observerList != null)
{
observerList.remove(observer);
}
}
/**
* 获取所有监听者
* @param key
* @return
*/
public List<DataObserver> getObservers(String key)
{
List<DataObserver> observerList = mObserverMap.get(key);
return observerList;
}
/**
* 删除该key的所有监听
* @param key
*/
public void removeObservers(String key)
{
mObserverMap.remove(key);
}
/**
* 获取所有监听key
* @return
*/
public Set<String> getAllKey()
{
return mObserverMap.keySet();
}
/**
* 删除该监听者的所有监听
* @param observer
*/
public void removeObserver(DataObserver observer)
{
Set<String> keySet = mObserverMap.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext())
{
String key = iterator.next();
List<DataObserver> observerList = mObserverMap.get(key);
observerList.remove(observer);
}
}
}
3.穿件完成后,就可以在baselogicmanager当中写几个方法来添加:
/**
* @param key 要监听的key
* @param observer 要被通知的observer
*/
protected void addObserver(String key, Object observer)
{
if (mObserverPool == null)
{
mObserverPool = new DataObserverPool();
}
DataObserver logicManagerObserver = new DataObserver(observer);
mObserverPool.addObserver(key, logicManagerObserver);
}
/**
*
* @param key 要移除监听的key
* @param observer 要被通知的observer
*/
protected void removeObserver(String key, Object observer)
{
if (mObserverPool == null) return;
List<DataObserver> logicManagerObservers = mObserverPool.getObservers(key);
if (logicManagerObservers == null) return;
DataObserver removeLogicManagerObserver = null;
for (DataObserver logicManagerObserver : logicManagerObservers)
{
if (observer == logicManagerObserver.getObserver())
{
removeLogicManagerObserver = logicManagerObserver;
break;
}
}
if (removeLogicManagerObserver != null)
{
mObserverPool.removeObserver(key,
removeLogicManagerObserver);
}
}
/**
*
* @param key
*/
protected List<Object> getObservers(String key)
{
List<Object> observerObjectList = new ArrayList<Object>();
if (mObserverPool == null)
return observerObjectList;
List<DataObserver> observers = mObserverPool.getObservers(key);
if (observers != null)
{
for (DataObserver observer : observers)
{
Object observerObject = observer.getObserver();
if (observerObject != null)
{
observerObjectList.add(observerObject);
}
}
}
return observerObjectList;
}
/**
*
* @param key
*/
protected void removeObservers(String key)
{
if (mObserverPool == null)
return;
mObserverPool.removeObservers(key);
}
/**
*
* @param observer
*/
protected void removeObserver(Object observer)
{
if (mObserverPool == null) return;
Set<String> keySet = mObserverPool.getAllKey();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext())
{
String key = iterator.next();
removeObserver(key, observer);
}
}
4.然后就到了实际的应用了,首先是得在interface当中设置好引用的接口
/**
* 添加对账户状态变化的观察
* @param observer
*/
void addAccountStateObserver(IAccountStateObserver observer);
/**
* 删除对账户状态变化的观察
* @param observer
*/
void removeAccountStateObserver(IAccountStateObserver observer);
interface IAccountStateObserver
{
void onAccountLogined();
void onAccountLogouted();
}
然后在accountmanager当中实现上面的两个方法:
@Override
public void addAccountStateObserver(IAccountStateObserver observer)
{
addObserver(OB_KEY_ACCOUNT_STATE, observer);
}
@Override
public void removeAccountStateObserver(IAccountStateObserver observer)
{
removeObserver(OB_KEY_ACCOUNT_STATE, observer);
}
5.例如我再addressManager当中要监听用户的状态是否发生了变化,就可以用这两个公共的方法来添加OB_KEY_ACCOUNT_STATE类的观察者:
public AddressManager()
{
LogicService.accountManager().addAccountStateObserver(this);
}
当然,AddressManager得首先实现IAccountStateObserver这个接口,然后就可以在两个接口当中对各自进行操作:
@Override
public void onAccountLogined()
{
}
@Override
public void onAccountLogouted()
{
mAddressList.clear();
mDefaultAddress = null;
}
6.最重要的事可别忘了,我们还没通知各个观察者,当然是在state发生变化时通知各个观察者:
例如我再请求用户信息,更新用户信息成功时,就可以通知管擦或者:
List<Object> observers = getObservers(OB_KEY_ACCOUNT_STATE);
if (observers != null)
{
for (Object object : observers)
{
IAccountStateObserver observer = (IAccountStateObserver) object;
observer.onAccountLogined();
}
}
或者
List<Object> observers = getObservers(OB_KEY_ACCOUNT_STATE);
if (observers != null)
{
for (Object object : observers)
{
IAccountStateObserver observer = (IAccountStateObserver) object;
observer.onAccountLogouted();
}
}
通过这样的设置,我们就可以通知各个观察者来进行各自的操作了,这样我们就能很方便的管理,不用每个类都去写各自的操作。
不足之处,望多多指教。