工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
1
2
3
4
5
6
7
8
|
public
class
Factory{
public
static
ISample creator(
int
which){
if
(which==
1
)
return
new
SampleA();
else
if
(which==
2
)
return
new
SampleB();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public
abstract
class
Factory{
public
abstract
Sample creator();
public
abstract
Sample2 creator(String name);
}
public
class
SimpleFactory
extends
Factory{
public
Sample creator(){
.........
return
new
SampleA
}
public
Sample2 creator(String name){
.........
return
new
Sample2A
}
}
public
class
BombFactory
extends
Factory{
public
Sample creator(){
......
return
new
SampleB
}
public
Sample2 creator(String name){
......
return
new
Sample2B
}
}
|
一个例子:
我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类。
先来一份兰州拉面(具体的产品类):
程序员加班必备也要吃泡面(具体的产品类):
还有我最爱吃的家乡的干扣面(具体的产品类):
准备工作做完了,我们来到一家“简单面馆”(简单工厂类),菜单如下:
简单面馆就提供三种面条(产品),你说你要啥,他就给你啥。这里我点了一份干扣面:
输出:
1 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。
2 create()方法通常是静态的,所以也称之为静态工厂。
1 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)
2 不同的产品需要不同额外参数的时候 不支持。
Class.forName(clz.getName()).newInstance()
实现的简单工厂:
点菜时:
输出:
1 它也是一个具体的类,非接口 抽象类。但它的create()方法,是利用反射机制生成对象返回,好处是增加一种产品时,不需要修改create()的代码。
这种写法粗看牛逼,细想之下,reflection的效率还有以下问题:
1 个人觉得不好,因为Class.forName(clz.getName()).newInstance()调用的是无参构造函数生成对象,它和new Object()是一样的性质,而工厂方法应该用于复杂对象的初始化 ,当需要调用有参的构造函数时便无能为力了,这样像为了工厂而工厂。
2 不同的产品需要不同额外参数的时候 不支持。
使用方法二 三实现的工厂,都有一个缺点:不同的产品需要不同额外参数的时候 不支持。
而且如果使用时传递的type、Class出错,将不能得到正确的对象,容错率不高。
而多方法的工厂模式为不同产品,提供不同的生产方法,使用时 需要哪种产品就调用该种产品的方法,使用方便、容错率高。
工厂如下:
使用时:
查看Java源码:java.util.concurrent.Executors
类便是一个生成Executor
的工厂 ,其采用的便是 多方法静态工厂模式:
例如ThreadPoolExecutor
类构造方法有5个参数,其中三个参数写法固定,前两个参数可配置,如下写。
又如JDK想增加创建ForkJoinPool
类的方法了,只想配置parallelism
参数,便在类里增加一个如下的方法:
这个例子可以感受到工厂方法的魅力了吧:方便创建 同种类型的 复杂参数 对象。
Android应用
我们知道Android中的fragment,listview,线程池会频繁调用,所以可以用工厂模式加以实现
public class FragmentFactory {
public static final int FRAGMENT_HOME = 0;
public static final int FRAGMENT_APP = 1;
public static final int FRAGMENT_GAME = 2;
public static final int FRAGMENT_SUBJECT = 3;
public static final int FRAGMENT_RECOMMEND = 4;
public static final int FRAGMENT_CATEGORY = 5;
public static final int FRAGMENT_HOT = 6;
//我们只要一个方法,就是得到我们需要的fragment
static SparseArrayCompat sparseArrayCompat = new SparseArrayCompat();
public static BaseFragment getFragment(int position) {
BaseFragment fragment = null;
//为了优化性能,我们还可以创建一个缓存,类似于luCache,这个叫做sparsearray稀疏数组
fragment= sparseArrayCompat.get(position);
if(fragment!=null){
return fragment;
}
switch (position) {
case FRAGMENT_HOME:// 主页
fragment = new HomeFragment();
break;
case FRAGMENT_APP:// 应用
fragment = new AppFragment();
break;
case FRAGMENT_GAME:// 游戏
fragment = new GameFragment();
break;
case FRAGMENT_SUBJECT:// 专题
fragment = new SubjectFragment();
break;
case FRAGMENT_RECOMMEND:// 推荐
fragment = new RecommendFragment();
break;
case FRAGMENT_CATEGORY:// 分类
fragment = new CategoryFragment();
break;
case FRAGMENT_HOT:// 排行
fragment = new HotFragment();
break;
default:
break;
}
sparseArrayCompat.put(position, fragment);
return fragment;
}
}
public class ListViewFactory {
public static ListView createListView() {
ListView mlistView = new ListView(UIUtils.getContext());
// 简单的设置
mlistView.setCacheColorHint(Color.TRANSPARENT);
mlistView.setFastScrollEnabled(true);
mlistView.setSelector(new ColorDrawable(Color.TRANSPARENT));
return mlistView;
}
}
public class ThreadPoolFactory {
static ThreadPoolProxy normalProxy;
static ThreadPoolProxy downloadProxy;
public static ThreadPoolProxy getNormalProxy() {
if(normalProxy==null){
synchronized (ThreadPoolProxy.class) {
if(normalProxy==null){
normalProxy = new ThreadPoolProxy(5, 5, 3000);
}
}
}
return normalProxy;
}
public static ThreadPoolProxy getdownloadProxy() {
if(downloadProxy==null){
synchronized (ThreadPoolProxy.class) {
if(downloadProxy==null){
downloadProxy = new ThreadPoolProxy(3, 3, 3000);
}
}
}
return downloadProxy;
}
}
感谢各位前辈文章的借鉴,我只是在前人的基础上融合了一下,我们看的更远是因为站在巨人的肩膀上