这个设计模式在Android中的用处不是太多,但是也有情况会用的到,对程序的扩展和健壮有很大的作用,也能比较好定位问题,所以我也是在网上找了资料然后根据场景谢了这个博客来记录一下自己所学习到的知识点。
首先说一下场景,比较适用于我们通过switch语句进行判断来创建对象的时候,app的首页我们知道都是比较复杂的,这个时候我们会根据服务器给的不同的item显示类型来创建不同的itemAdapter用来展示行内容,所以我们首先创建一个BaseAdapter,比较简陋的代码,这里需要你们集成Android自己的RecycleAdapter来实现布局展示逻辑,我这里省略了,代码如下:
abstract public class BaseAdapter implements NullableInterface{ private static final String TAG = "BaseAdapter"; @Override public void doAction() { isNull(); doSomeThing(); } @Override public boolean isNull() { Log.e(TAG + " - lcs - ", "对象不为空!!!"); return false; } abstract void doSomeThing(); }
首先这是个抽象类,为了暴露给子类我们的doSomeThing方法,这里我们还要实现自己的接口NullableInterface,代码如下:
public interface NullableInterface { void doAction(); boolean isNull(); }
然后我们在定义实际中我们所需要的行itemAdapter,这里随便写了两个,第一个OneAdapter,代码如下:
public class OneAdapter extends BaseAdapter { private static final String TAG = "OneAdapter"; @Override void doSomeThing() { Log.e(TAG + " - lcs - ", "OneAdapter is doing something"); } }
第二个TwoAdapter,代码如下:
public class TwoAdapter extends BaseAdapter{ private static final String TAG = "TwoAdapter"; @Override void doSomeThing() { Log.e(TAG + " - lcs - ", "TwoAdapter is doing something"); } }
接下来还有一个最重要的我们的空指针的时候我们的对象的adapter,NullAdapter,代码如下:
public class NullAdapter extends BaseAdapter implements NullableInterface { private static final String TAG = "NullAdapter"; @Override public void doAction() { isNull(); doSomeThing(); } @Override public boolean isNull() { Log.e(TAG + " - lcs - ", "警告! 对象为空!!!"); return true; } @Override void doSomeThing() { Log.e(TAG + " - lcs - ", "NullAdapter is doing something"); } }
可以看到我们的log打印的代码都有标记。
最后我们的工厂类,BaseFactory,代码如下:
public class BaseFactory { public static BaseAdapter create(String type){ BaseAdapter baseAdapter = null; switch (type) { case "1": baseAdapter = new OneAdapter(); break; case "2": baseAdapter = new TwoAdapter(); break; default: baseAdapter = new NullAdapter(); break; } return baseAdapter; } }
可以看到我们的默认default我们返回的不是null,而是我们自己定义的空指针的Adapter,然后再测试代码:
for (int i = 0; i < 3; i++) { BaseFactory.create(i + "").doAction(); }
这时候就会报错了,当然了我们也可以进行空指针的判断,那么这样的代码也是可以的,不过不完美,不健壮,我们不可能所有的地方都要加上if(null)的判断,所以我们这样的设计模式就可以很好地解决这样的问题,还能很好地定位问题,运行代码可以看到输出内容如下:
05-29 16:00:16.712 1061-1061/com.example.jiaoben E/NullAdapter - lcs -: 警告! 对象为空!!!
05-29 16:00:16.712 1061-1061/com.example.jiaoben E/NullAdapter - lcs -: NullAdapter is doing something
05-29 16:00:16.712 1061-1061/com.example.jiaoben E/BaseAdapter - lcs -: 对象不为空!!!
05-29 16:00:16.712 1061-1061/com.example.jiaoben E/OneAdapter - lcs -: OneAdapter is doing something
05-29 16:00:16.712 1061-1061/com.example.jiaoben E/BaseAdapter - lcs -: 对象不为空!!!
05-29 16:00:16.712 1061-1061/com.example.jiaoben E/TwoAdapter - lcs -: TwoAdapter is doing something
很明显我们程序没有报错,我们也能够很清楚的看到我们的错误信息,这样即便是服务器出错误返回了我们客户端没有的类型,那么也不至于app会崩溃,也算是一种优雅的方式来解决这样的问题!