Java接口与实现的分离以及隐藏实现
作者:元亨利贞o 发布时间:[ 2017/1/16 11:17:18 ] 推荐标签:接口测试 Java
(3) 为实现类定义初始化工厂类
class ImageLoaderFactory {
private static ImageLoader mImageLoader;
private ImageLoaderFactory() {
//no instance
}
/**
* @return
*/
public static ImageLoader createImageLoader(String implClass) {
if (mImageLoader == null) {
mImageLoader = createImageLoaderWithClassName(implClass);
}
return mImageLoader;
}
/**
* 此处使用类反射, 所有implClass都不能混淆, 类名必须keep: {@code -keep class a.b.c.ImplClass}
* @param implClass 实现类有: FrescoImageLoader, GlideImageLoader, PicassoImageLoader, UILImageLoader
* @return
*/
private static ImageLoader createImageLoaderWithClassName(String implClass) {
try {
Class klass = Class.forName(implClass);
Constructor constructor = klass.getDeclaredConstructor();
if (constructor == null) {
throw new RuntimeException(implClass + " 的实现类必须有一个无参构造方法 !");
}
boolean isAccessible = constructor.isAccessible();
constructor.setAccessible(true);
Object obj = constructor.newInstance();
constructor.setAccessible(isAccessible);
if ( !(obj instanceof ImageLoader) ) {
throw new RuntimeException(implClass + "必须实现" + ImageLoader.class.getName() + "接口");
}
ImageLoader imageLoader = (ImageLoader) obj;
return imageLoader;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
(4) 要使用ImageLoader, 直接用工厂类创建即可, 我们只需要知道实现类的名称, 其它细节都不需要知道. 实现类都是高度内聚, 外部完全不知道其内部的逻辑. 外部只需要调用接口的方法实现业务逻辑即可. 下面是ImageLoader及其相关实现的整体结构:
接口与实现分离, 隐藏实现
(5) 下面是使用工厂类创建ImageLoader实现的代码
import android.content.Context;
public final class ImageManager {
private static String TAG = "ImageManager";
private static ImageLoader sImageLoader;
private ImageManager() {
//no instance
}
public static void init(Context appContext) {
if (sImageLoader != null) {
throw new IllegalStateException(TAG + " already initalized");
}
sImageLoader = ImageLoaderFactory.createImageLoader("com.stone.app.manager.imageloader.internal.FrescoImageLoader");
sImageLoader.init(appContext);
}
public static ImageLoader getImageLoader() {
return sImageLoader;
}
}
总结:
将接口和实现类分离, 接口和实现分别放在单独的包中, 并且实现类定义为包私有的 (即类没有修饰符).
定义工厂类, 使用反射初始化实现类.
注意混淆的时候不能混淆实现类的类名, 因为其初始化使用了反射.
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11