项目开发时,一般都会有图片加载、地图等需求,而这些一般使用第三方库,例如图片加载可能会选择Glide、Picasso、Fresco等其中的一种,地图可供选择的有百度地图、高德地图、华为地图(即将发布),那么怎样将其集成到项目中呢?直接将相关的功能加入到业务逻辑中吗?那么突然有一天要将现有使用换成另一种呢?例如现在图片加载使用的是Glide框架,突然要换成Fresco,此时怎么办?要吭哧吭哧再将相关逻辑再写一遍吗?
当然不能,因为这不符合程序员“懒”的特质,那怎么办?好,那借此机会啰嗦一下面向对象(OOP)设计原则:
面向对象程序几大设计原则
基于以上原则,来封装引入第三方服务,以图片加载为例:
- 首先基于依赖倒置原则使用接口实现图片加载的逻辑:
public interface ILoader {
void load(Context context, ImageView imageView, @DrawableRes int drawableRes);
void load(Context context, ImageView imageView, String url);
void load(Context context, ImageView imageView, byte[] image);
void load(Context context, ImageView imageView, @DrawableRes int drawableRes, @DrawableRes int errorResId, @DrawableRes int placeholderResId);
void load(Context context, ImageView imageView, String url, @DrawableRes int errorResId, @DrawableRes int placeholderResId);
void load(Context context, ImageView imageView, byte[] image, @DrawableRes int errorResId, @DrawableRes int placeholderResId);
}
- 具体实现由其子类完成:
public class GlideLoader implements ILoader {
@Override
public void load(Context context, ImageView imageView, int drawableRes) {
Glide.with(context)
.load(drawableRes)
.into(imageView);
}
@Override
public void load(Context context, ImageView imageView, String url) {
Glide.with(context)
.load(url)
.into(imageView);
}
@Override
public void load(Context context, ImageView imageView, byte[] image) {
Glide.with(context)
.load(image)
.into(imageView);
}
@Override
public void load(Context context, ImageView imageView, int drawableRes, int errorResId, int placeholderResId) {
Glide.with(context)
.load(drawableRes)
.apply(getRequestOptions(errorResId, placeholderResId))
.into(imageView);
}
@Override
public void load(Context context, ImageView imageView, String url, int errorResId, int placeholderResId) {
Glide.with(context)
.load(url)
.apply(getRequestOptions(errorResId, placeholderResId))
.into(imageView);
}
@Override
public void load(Context context, ImageView imageView, byte[] image, int errorResId, int placeholderResId) {
Glide.with(context)
.load(image)
.apply(getRequestOptions(errorResId, placeholderResId))
.into(imageView);
}
}
- 然后统一使用Manager管理:
public class ImageLoader implements ILoader {
private ILoader mImageLoader;
private static ImageLoader imageManager;
private ImageLoader() {
}
public static ImageLoader getInstance() {
if (imageManager == null) {
synchronized (ImageLoader.class) {
if (imageManager == null) {
imageManager = new ImageLoader();
}
}
}
return imageManager;
}
public void setImageLoader(ILoader imageLoader) {
mImageLoader = imageLoader;
}
@Override
public void load(Context context, ImageView imageView, int drawableRes) {
mImageLoader.load(context, imageView, drawableRes);
}
@Override
public void load(Context context, ImageView imageView, String url) {
mImageLoader.load(context, imageView, url);
}
@Override
public void load(Context context, ImageView imageView, byte[] image) {
mImageLoader.load(context, imageView, image);
}
@Override
public void load(Context context, ImageView imageView, int drawableRes, int errorResId, int placeholderResId) {
mImageLoader.load(context, imageView, drawableRes, errorResId, placeholderResId);
}
@Override
public void load(Context context, ImageView imageView, String url, int errorResId, int placeholderResId) {
mImageLoader.load(context, imageView, url, errorResId, placeholderResId);
}
@Override
public void load(Context context, ImageView imageView, byte[] image, int errorResId, int placeholderResId) {
mImageLoader.load(context, imageView, image, errorResId, placeholderResId);
}
}
- 使用时先设置setImageLoader(),然后通过ImageLoader直接调用:
//在Application中设置
private void setImageLoader() {
ImageLoader.getInstance().setImageLoader(new GlideLoader());
}
- 全局使用,例如:
@Override
protected void initView() {
super.initView();
ImageLoader.getInstance().load(getContext(), mImgMainActImg, R.mipmap.ic_launcher_round);
}
6.突然技术改变要更换成Picasso,那么直接实现PicassoLoader,设置 ImageLoader.getInstance().setImageLoader(new PicassoLoader())即可,原有逻辑一下也不需要动
备注:Fresco加载图片使用的是自定义View控件加载图片,所以以上ImageView修改为View更佳
回过头来分析下,此图片加载框架封装几乎使用了上述所有的设计原则,也可推广到地图和其他,读者有不同观点或改进建议请留言一起交流一下!