上一篇 OkHttp设计模式剖析(七)迭代器模式
OKHTTP:
由大名鼎鼎的Square公司开发的网络通信库。
设计模式:
软件开发中问题的解决套路。
工厂模式简介
定义:定义一个算法的框架,二将一些步骤延迟到子类中,使子类可以不改变算法的结构即可重新定义某些特定步骤。
在任何需要生成复杂对象的地方,都可以使用工厂模式,复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
因为现实代码中,当工厂很复杂,产品也很复杂时,工厂生产产品(不分离)这个类就及其复杂难以管理。工厂模式事实上就是用一个“接口”,将工厂和产品解耦(将创建对象和使用对象解耦),这样代码好管理。
若源代码中有Factory这个词,大概率使用了工厂模式。
Call.Factory接口中的工厂模式
平时使用OkHttp框架都是用下面的套路:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().build();
Response response = client.newCall(request).execute();
其中OkHttpClient.java中的newCall函数源码如下
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
上述源码其实是在实现Call接口
public interface Call extends Cloneable {
Request request();
Response execute() throws IOException;
void enqueue(Callback responseCallback);
void cancel();
boolean isExecuted();
boolean isCanceled();
Call clone();
interface Factory { // 此处就是上述源码实现Factory接口
Call newCall(Request request);
}
}
一言以蔽之,OkhttpClient实现了Call.Factory接口。其实此处的工厂模式并不典型,包括OkHttp框架中RealCall实现Call接口用的工厂模式也并典型。因为他只要Call一个子类,也只用RealCall实现该子类。换句话说,这个工厂的产品只有一个。但是这里用到了工厂模式的中心思想,将搭建复杂对象将的细节交待给RealCall实现,我们只管得到Call即可。
基于工厂模式构建的其他代码
1、OkHttp框架中RealCall实现Call接口
2、Android源码中的onCreate方法
简单工厂模式(静态工厂模式)示例
// 产品的抽象类
public abstract class Product {
public abstract void manufacture();
}
// 产品A(宜宾燃面)的具体实现
public class ConcreteProA extends Product{
@Override
public void manufacture() {
System.out.println("我是宜宾燃面!");
}
}
// 这是一个简单工厂
public class Factory {
public static Product createProduct() { // 注意这个static
return new ConcreteProA();
}
}
若工厂类只有一个,就是只生产一种产品,那么就简化掉抽象类,将工厂方法改成静态方法。
我们将这个示例跑一下
public class Main {
public static void main(String[] args){
Factory f = new Factory();
Product p = f.createProduct();
p.manufacture();// 输出: 我是宜宾燃面!
}
}
这个工厂可以一直生产宜宾燃面。其实这样看起来,没必要用工厂啊,就直接做面就好啊。但事实上,我们屏蔽了工厂里面采购、和面、调酱等过程,只管拿生产出来的宜宾燃面。同时,工厂也不去管你宜宾燃面是自己吃还是请别人吃。互相屏蔽,不打搅。
参考文献
1、设计模式|菜鸟教程:https://www.runoob.com/design-pattern/design-pattern-tutorial.html
2、《Android源码设计模式解析与实战》何红辉,关爱民著
3、隔壁老李头:https://www.jianshu.com/p/82f74db14a18