简单(静态)工厂:
一个栗子:
我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类。
public abstract class INoodles {
/**
* 描述每种面条啥样的
*/
public abstract void desc();
}
先来一份兰州拉面(具体的产品类):
public class LzNoodles extends INoodles {
@Override
public void desc() {
System.out.println("兰州拉面 上海的好贵 家里才5 6块钱一碗");
}
}
程序员加班必备也要吃泡面(具体的产品类):
public class PaoNoodles extends INoodles {
@Override
public void desc() {
System.out.println("泡面好吃 可不要贪杯");
}
}
还有我最爱吃的家乡的干扣面(具体的产品类):
public class GankouNoodles extends INoodles {
@Override
public void desc() {
System.out.println("还是家里的干扣面好吃 6块一碗");
}
}
准备工作做完了,我们来到一家“简单面馆”(简单工厂类),菜单如下:
public class SimpleNoodlesFactory {
public static final int TYPE_LZ = 1;//兰州拉面
public static final int TYPE_PM = 2;//泡面
public static final int TYPE_GK = 3;//干扣面
public static INoodles createNoodles(int type) {
switch (type) {
case TYPE_LZ:
return new LzNoodles();
case TYPE_PM:
return new PaoNoodles();
case TYPE_GK:
default:
return new GankouNoodles();
}
}
}
简单面馆就提供三种面条(产品),你说你要啥,他就给你啥。这里我点了一份干扣面:
/**
* 简单工厂模式
*/
INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK);
noodles.desc();
输出:
还是家里的干扣面好吃 6块一碗
特点
1 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。
2 create()方法通常是静态的,所以也称之为静态工厂。
缺点
1 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)
2 不同的产品需要不同额外参数的时候 不支持。
多方法工厂(常用)
使用方法二 三实现的工厂,都有一个缺点:不同的产品需要不同额外参数的时候 不支持。
而且如果使用时传递的type、Class出错,将不能得到正确的对象,容错率不高。
而多方法的工厂模式为不同产品,提供不同的生产方法,使用时 需要哪种产品就调用该种产品的方法,使用方便、容错率高。
工厂如下:
public class MulWayNoodlesFactory {
/**
* 模仿Executors 类
* 生产泡面
*
* @return
*/
public static INoodles createPm() {
return new PaoNoodles();
}
/**
* 模仿Executors 类
* 生产兰州拉面
*
* @return
*/
public static INoodles createLz() {
return new LzNoodles();
}
/**
* 模仿Executors 类
* 生产干扣面
*
* @return
*/
public static INoodles createGk() {
return new GankouNoodles();
}
}
使用时:
/**
* 多方法静态工厂(模仿Executor类)
*/
System.out.println("==============================模仿Executor类==============================" +
"\n 这种我比较青睐,增加一个新面条,只要去增加一个static方法即可,也不修改原方法逻辑");
INoodles lz2 = MulWayNoodlesFactory.createLz();
lz2.desc();
INoodles gk2 = MulWayNoodlesFactory.createGk();
gk2.desc();
输出:
==============================模仿Executor类==============================
这种我比较青睐,增加一个新面条,只要去增加一个static方法即可,也不修改原方法逻辑
兰州拉面 上海的好贵 家里才5 6块钱一碗
还是家里的干扣面好吃 6块一碗
源码撑腰环节
查看java源码:java.util.concurrent.Executors
类便是一个生成Executor
的工厂 ,其采用的便是 多方法静态工厂模式:
例如ThreadPoolExecutor
类构造方法有5个参数,其中三个参数写法固定,前两个参数可配置,如下写。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
又如JDK想增加创建ForkJoinPool
类的方法了,只想配置parallelism
参数,便在类里增加一个如下的方法:
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
这个例子可以感受到工厂方法的魅力了吧:方便创建 同种类型的 复杂参数 对象。