二次封装图片第三方框架——简单工厂模式的运用

从上面的分析,我们知道,采用简单工厂模式,一般需要三个步骤

  • 抽象Product的共同特点,定义成一个接口或者抽象类

  • ConcreteProduct的具体实现

  • 实现Factory

下面我们一起来看一下怎样运用于替换图片框架上


简单工厂模式的运用——几行代码更换图片框架


首先为了加深理解,我们一起先来看一下类UML图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接着按照上面的三部曲,第一步,我们先定义一个接口IimageListener,用来统一参数

public interface IimageListener {

void display(Context context, ImageView imageView, String url, int progressId, int errorId,

Object tag);

void display(Context context, ImageView imageView, String url, int progressId, int errorId);

void display(Context context, ImageView imageView, String url, int progressId);

void display(Context context, ImageView imageView, String url);

void display(Context context, ImageView imageView, Uri uri);

}

第二步,我们来写GlideRequest和PicassoRequest的具体实现

public class GlideRequest implements IimageListener {

@Override

public void display(Context context, ImageView imageView, String url, int progressId, int

errorId, Object tag) {

DrawableTypeRequest load = Glide.with(context).load(url);

if (progressId != -1) {

load.placeholder(progressId).centerCrop();

} else {

load.placeholder(new ColorDrawable(Color.GRAY));

}

if (errorId != -1) {

load.error(errorId);

}else{

load.error(R.drawable.ic_error);

}

load.into(imageView);

}

@Override

public void display(Context context, ImageView imageView, String url, int progressId, int

errorId) {

display(context, imageView, url, progressId, errorId, null);

}

@Override

public void display(Context context, ImageView imageView, String url, int progressId) {

display(context, imageView, url, progressId, -1, null);

}

@Override

public void display(Context context, ImageView imageView, String url) {

display(context, imageView, url, -1, -1, null);

}

@Override

public void display(Context context, ImageView imageView, Uri uri) {

DrawableTypeRequest load = Glide.with(context).load(uri);

load.into(imageView);

}

}

public class PicassoRequest implements IimageListener {

@Override

public void display(Context context, ImageView imageView, String url, int progressId, int

errorId, Object tag) {

Picasso.with(context).load(url).placeholder(progressId).error(errorId).tag(tag).into(imageView);

}

@Override

public void display(Context context, ImageView imageView, String url, int progressId, int

errorId) {

Picasso.with(context).load(url).placeholder(progressId).error(errorId).into(imageView);

}

@Override

public void display(Context context, ImageView imageView, String url, int progressId) {

Picasso.with(context).load(url).placeholder(progressId).into(imageView);

}

@Override

public void display(Context context, ImageView imageView, String url) {

Picasso.with(context).load(url).into(imageView);

}

@Override

public void display(Context context, ImageView imageView, Uri uri) {

Picasso.with(context).load(uri).into(imageView);

}

}

第三步,我们来写工厂类ImageRequestManager的实现,可以看到我们可以根据不同的参数返回不同的实例,进而来决定使用Picasso或者是Glide

public class ImageRequestManager {

public static final String type_Glide=“Glide”;

public static final String type_Picasso=“Picasso”;

public static final String type_default =type_Glide;

private ImageRequestManager(){

}

public static IimageListener getRequest(){

return getRequest(type_default);

}

public static IimageListener getRequest(String type){

switch (type){

case type_Glide:

return new GlideRequest();

case type_Picasso:

return new PicassoRequest();

default:

return new GlideRequest();

}

}

}

最后,以后我们想加载图片只需简单调用下面的方法就OK了,简单明了,再也不用怕替换框架了

ImageRequestManager.getRequest().display(mContext, imageView, imageUrl);

讨论

情景一:之前我是使用Glide框架,现在想使用Picasso框架,那要怎么办呢?

只需将 ImageRequestManager 里面的 String type_default=type_Glide 更改为String type_default=type_Picasso 就ok了。

//public static final String type_default =type_Glide;

public static final String type_default =type_Picasso;

情景二:有人会说了,平时在项目中基本只会使用一种图片加载框架,要么使用Picasso,要么使用Glide,你这样做同时使用了两种框架,无疑增加了APK的大小,那要怎么办呢?其实很简单

如果你只想使用Picasso,去掉Glide的具体实现就OK了,同理你只想使用Glide,去掉Picasso的具体实现就好了,不过建议保留空方法,以后要修改就不必更改工厂类 ImageRequestManager 里面的逻辑呢


简单工厂模式总结


  • 将对象的创建工作与对象的业务逻辑分析,降低了系统的耦合度

  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。为了调用者的方便,我们可以给工厂类添加一个默认参数,这样调用的时候不必每次传入参数

  • 从上面知道的例子,我们知道,业务逻辑大部分在工厂类里面,如果工厂类需要创建的对象不多的话,简单工厂方法模式还是很有很大的优势的,而如果需要创建很多对象的话,那工厂里面无疑要增加很多case 语句,这样会导致工厂类的职责太重了,破坏了类的单一性。

综上所述:

简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。

简单工厂模式适用情况包括:工厂类负责创建的对象比较少;客户端只知道传入工厂类的参数,对于如何创建对象不关心。


扩展

看了上面的文章,对于于Volley,OKhttp等网络框架的简单封装,你是不是也想到了什么,应该懂得怎么封装了吧。

而对于Retrofit的封装,你有没有想到了什么呢?因为Retrofit的返回对象比较特殊,是 Observable<>,更其他的网络框架不太一样,其实还是可以大概处理一下的,这里暂时就不讨论了,大家有兴趣的可以自己先去尝试,相信你会收获到很多东西的。


题外话


万丈高楼平地起,对于程序猿的我们,一定要多动手实践,我相信很多同学看到这里,都基本掌握了,但是很有很多同学不动手去实践一下,就这样,几天过去了,似懂非懂,最后忘记了,而这恰恰是分水岭。哈哈,就扯蛋这么多了。


最后给出github地址,上面的小项目是我平时没事写写玩玩的。

最后

**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。



《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
的我们,一定要多动手实践,我相信很多同学看到这里,都基本掌握了,但是很有很多同学不动手去实践一下,就这样,几天过去了,似懂非懂,最后忘记了,而这恰恰是分水岭。哈哈,就扯蛋这么多了。


最后给出github地址,上面的小项目是我平时没事写写玩玩的。

最后

**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。


[外链图片转存中…(img-QAYKjXSu-1715176335351)]

[外链图片转存中…(img-pZDLJyq8-1715176335351)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值