设计模式系列:
0. Android开发常用设计模式;
一、常见需求场景
三毛:“小白,下面支付宝截图中的红框网格列表,要是给你做,你会怎么做”
二、基本解决方法
小白:,毛毛哥问的话,肯定不能一行一个LinearLayout了,可以用GridView或Recyclerview,我这里用RecyclerView吧,代码如下
存储内容实体类
public class TopBean {
public int topImg;//图片
private String titleStr;//标题内容
//set、get方法这里省略了
}
设置适配器
ArrayList<TopBean> list = new ArrayList<>();
for (int i = 0; i < 12; i++) {
TopBean topBean = new TopBean();
topBean.setTopImg(R.mipmap.ic_launcher);
topBean.setTitleStr("item标题"+i);
list.add(topBean);
}
AlipayAdapter alipayAdapter = new AlipayAdapter(R.layout.adapter_layout, list);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 4);
mRecyclerView.setLayoutManager(gridLayoutManager);
mRecyclerView.setAdapter(alipayAdapter);
alipayAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
switch (position){
case 0:
//跳到界面A....
break;
case 1:
//跳到界面B....
break;
case 2:
//跳到界面C....
break;
//...后面省略了
}
}
});
三毛:“嗯,用ReyclerView来实现确实比一个行一个LinearLayout好些,但是你的每一项点击事件用switch来判断跳转”
小白:额,确实这样不好看,但是我没其他办法了哇,只能这样了
三、基本解决方法存在的问题
三毛:“难看是一点,其实我想说的是,如果因为需求在增加几个item,你ReyclerView里面不得在加多几个判断(维护扩展不友好),而且别人一看你代码鬼知道你0 1 2 3 4….是啥(阅读不友好)”
小白:呐,毛毛哥指点指点呗,我上面可以怎样改进呢
四、策略模式写法
策略模式定义:定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
三毛:“那我这里就使用策略模式来改进你上面的写法吧”
//写一个通用的item接口
public interface IItem {
//用于跳转
void toActivity();
//在适配器里使用该方法获取图片
int getTopImg();
//在适配器里使用该方法获取标题
String getTitleStr();
}
//A item 操作类
public class AItem implements IItem {
@Override
public void toActivity() {
//跳到界面A....
}
//下面get方法给适配器调用
public int getTopImg() {
return R.mipmap.ic_launcher;
}
public String getTitleStr() {
return "A标题";
}
}
//B item 操作类
public class BItem implements IItem {
@Override
public void toActivity() {
//跳到界面B....
}
//下面get方法给适配器调用
public int getTopImg() {
return R.mipmap.ic_launcher;
}
public String getTitleStr() {
return "B标题";
}
}
//剩下C、D、E....item就不贴了,一个道理
适配器设置
ArrayList<IItem> list = new ArrayList<>();
AItem aItem = new AItem();
BItem bItem = new BItem();
//....
list.add(aItem);
list.add(bItem);
//...
AlipayAdapter alipayAdapter = new AlipayAdapter(R.layout.adapter_layout, list);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 4);
mRecyclerView.setLayoutManager(gridLayoutManager);
mRecyclerView.setAdapter(alipayAdapter);
alipayAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
//这时候就不需要用switch判断了
IItem iItem = (IItem) adapter.getData().get(position);
iItem.toActivity();
}
});
适配器里面
//这里的适配器是封装过的(所以只贴设置数据的地方)
@Override
protected void convert(BaseViewHolder holder, IItem item) {
//直接调用get方法设置数据
holder.setImageResource(R.id.top_img,item.getTopImg())
.setText(R.id.tv_title,item.getTitleStr());
}
小白:不过每个item都要new一个对象好麻烦的说
三毛:“非要说麻烦,确实有点点,但是当你业务需求需要增加或修改什么的时候,你就可以直接在对应的item对象里操作了,而且每个item对象又相互不影响,别人看也清晰很多”
小白:有点道理的样子
三毛:“什么叫有点 而且这里为了给你说清楚策略模式的使用才没有在多封一下的”
小白:喔,酱紫吖
三毛:“我的白,人是活的,原理是死的,我们在去学习的时候不要老拘泥于这些东西,当你熟烂的使用时你自然而然就明白了,如果还有什么不清楚,也可以参考参考【设计模式】策略模式详解和Android 中的那些策略模式”
小白:嗯嗯,好的
五、策略模式和普通写法区别
1、每个需求模块都相互独立,方便测试;
2、耦合度更低,扩展性更强(设计模式通病?)
3、结构更加清晰,不会像一堆判断条件语句(大量 if-else 或者 switch)难看;