您的位置:首页 > 移动开发 > Android开发

Java设计模式之模板模式(Template)在Android中的应用

2015-11-01 01:56 756 查看
1.说到这个Template 模式,使用实在是太普遍了,并且非常容易理解。通俗一点的说法就是:我们定义一个抽象类,里面封装一些抽象方法,然后子类继承这个抽象类,实现这些抽象方法。这就是一个模板模式,它可以起到减少代码重复,规范子类行为的作用。

2.在Android开发中经常会看到先定义一个BaseActivity,然后后续的Activity都来继承这个BaseActivity,所以这个BaseActivity 就是一个模板了。我之前有一篇博客讲到了对activity的封装,那个就可以作为模板供以后一直使用。

3.后面开发的时候见识过一次非常好的模板封装,借助了构造方法和泛型对adapter进行第一次封装:

public abstract class MyBaseAdapter1<T> extends BaseAdapter {

private ArrayList<T> list;

// 构造方法的作用:从外界传递数据过来
public MyBaseAdapter1(ArrayList<T> list) {
this.list = list;
}

@Override
public int getCount() {
return list.size();
}

@Override
public T getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public abstract View getView(int position, View convertView,
ViewGroup parent);

}


4.adapter后面还进行了第二次封装:原理就是:在getView的方法中,ListView会用到ViewHolder 来优化, 我们仔细研究可以发现,holder可以做的事情有: 初始化item, findViewById(初始化子控件),设置标记setTag,刷新控件数据。所以可以将这些业务交给一个BaseHolder来做。这就是对adapter的第二次封装。

5.app开发过程中经常做的就是对网络访问,那么对获取数据 - 解析数据 - 网络缓存这一过程也可以封装成一个抽象类,后续子类调用,这也可以形成一个网络访问的模板:

public abstract class BaseProtocol<T> {

public T getData(int index) {
// 判断是否有缓存,有的话从缓存处取值
String result = getCache(index);
if (StringUtils.isEmpty(result)) {
// 访问网络
result = getDataFromServer(index);
}

if (result != null) {
return parseJson(result);
}
return null;
}

// 访问网络
private String getDataFromServer(int index) {
HttpResult httpResult = HttpHelper.get(HttpHelper.URL + getKey()
+ "?index=" + index + getParams());
if (httpResult != null) {
String result = httpResult.getString();// 返回jason字符串
if (!StringUtils.isEmpty(result)) {
// 写入缓存
setCache(result, index);
}
return result;
}
return null;
}

/**
* 以url(包含参数)为key(文件名), 以json为value(文件内容), 保存在本地 MD5(url)
*
* @param result
* @param index
*/
private void setCache(String jason, int index) {
File cacheDir = UIUtils.getContext().getCacheDir();
File cacheFile = new File(cacheDir, getKey() + "?index=" + index
+ getParams());
// 开始写入文件
FileWriter writer = null;
try {
writer = new FileWriter(cacheFile);
// 文件第一行写缓存有效期限
long deadline = System.currentTimeMillis() + 30 * 60 * 1000;
writer.write(deadline + "\n");
writer.write(jason);
writer.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.close(writer);
}
}

/**
* 获取缓存文件
*
* @return
*/
public String getCache(int index) {
File cacheDir = UIUtils.getContext().getCacheDir();
File cacheFile = new File(cacheDir, getKey() + "?index=" + index
+ getParams());
if (cacheFile.exists()) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(cacheFile));
String firstLine = reader.readLine();
long deadline = Long.parseLong(firstLine);
// 如果deadline还在有效期限内,则从缓存取文件
if (deadline < System.currentTimeMillis()) {
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
// 将读的内容拼接成字符串
sb.append(line);
}
return sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.close(reader);
}
}
return null;
}

// 由子类实现,带参数访问网络
public abstract String getKey();

public abstract String getParams();

public abstract T parseJson(String jason);
}


6.所以,我们可以看到,Template 无处不在。我们在开发过程中也可以根据实际需求,自己定义出一个Template,减少重复性的工作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息