从上面的分析,我们知道,采用简单工厂模式,一般需要三个步骤
-
抽象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学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!