(点击
上方公众号
,可快速关注)
来源:伯乐在线专栏作者 - PleaseCallMeCoder
链接:http://android.jobbole.com/84840/
点击 → 了解如何加入专栏作者
写在前面的话
在上一篇《
Android 源码中的静态工厂方法
》中我
们
一起研究了工厂模式三兄弟中最简单的静态工厂方法。今天我们来一起看看三兄弟中的老二————工厂方法模式,以及它在Android源码中的体现。
今天我们先来模拟一个场景,把这三兄弟拎出来给大家瞅瞅,以免以后大家认错。
-
今天我们决定进军手机行业,手机名字叫做aPhone。我们要做一个aPhone1的样品。————我们的直接new一个aPhone1对象就好了
-
我们的aPhone1卖的巨火,挡都挡不住,我们要出aPhone2、aPhone3、aPhone4等等一系列手机。————我们可以通过简单工厂方法来生产手机(老三)
-
我们的aPhone系列手机配置比较高,考虑到市场上对低端产品的需求,我们要做aPhoneNote系列手机。————我们可以通过工厂方法模式来生产(老二)
-
由于我们aPhone6系列手机的屏幕生产时出现了问题,导致手机寿命降低,给公司造成了很大的损失。现在我们要从零件方面来把控产品质量,屏幕、电池、主板等零件的质量我们都要做质检。————我们可以通过抽象工厂来生产(老大)
这就是工厂三兄弟。
工厂方法模式
定义
工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。
工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
结构
工厂方法模式所涉及到的角色:
-
Product(抽象产品角色)
:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
-
ConcreteProduct(具体产品角色)
:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
-
Factory(抽象工厂角色)
:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
-
ConcreteFactory(具体工厂角色)
:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
实现
我们用我们上边手机的例子来实现。
抽象产品角色
abstract
class
APhone
{
//所有产品类的公共业务方法
public
void
methodSame
()
{
//公共方法的实现
}
//声明抽象业务方法
public
abstract
void
methodDiff
();
}
具体产品角色类,这里我们只说一类,比如我们的aPhoneNote系列手机
class
APhoneNote1
extends
APhone
{
//实现业务方法
public
void
methodDiff
()
{
//业务方法的实现
}
}
抽象工厂角色
abstract
class
Factory
{
//静态工厂方法
public
abstract
APhone createProduct
(
String
arg
)
;
}
具体工厂角色,这里我们只说生产aPhoneNote系列手机的工厂
class
ConcreteFactory
{
//静态工厂方法
public
APhone createProduct
(
String
arg
)
{
APhone
aPhoneNote
=
null
;
if
(
arg
.
equalsIgnoreCase
(
"1"
))
{
aPhoneNote
=
new
APhoneNote1
();
//初始化设置product
}
else
if
(
arg
.
equalsIgnoreCase
(
"
2
))
{
aPhoneNote
=
new
APhoneNote2
();
//初始化设置product
}
return
aPhoneNote
;
}
}
使用场景
-
需要创建复杂对象
-
需要灵活、可扩展的框架,且具体类型不多
Android中工厂方法模式的应用
Java中的类集框架
我们在开发中会用到很多数据结构,比如ArrayList,HashMap等。我们先来看下Java中Collection部分的类集框架的简要UML图。
我们知道Iterator是迭代器,用来遍历一个集合中的元素。而不同的数据结构遍历的方式是不一样的,所以迭代器的实现也是不同的。使用工厂方法模式将迭代器的具体类型延迟到具体容器类中,比较灵活,容易扩展。
List和Set继承自Collection接口,Collection接口继承于Iterable接口。
public
interface
Iterable
T
>
{
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator
T
>
iterator
();
//省略部分代码
}
所以List和Set接口也会继承该方法。然后我们常用的两个间接实现类ArrayList和HashSet中的iterator方法就给我们构造并返回了一个迭代器对象。
我们找到ArrayList类,查看iterator方法的实现。
@
Override
public
Iterator
E
>
iterator
()
{
return
new
ArrayListIterator
();
}
ArrayListIterator类型定义如下:
private
class
ArrayListIterator
implements
Iterator
E
>
{
/** Number of elements remaining in this iteration */
private
int
remaining
=
size
;
/** Index of element that remove() would remove, or -1 if no such elt */
private
int
removalIndex
= -
1
;
/** The expected modCount value */
private
int
expectedModCount
=
modCount
;
public
boolean
hasNext
()
{
return
remaining
!=
0
;
}
@
SuppressWarnings
(
"unchecked"
)
public
E
next
()
{
ArrayList
E
>
ourList
=
ArrayList
.
this
;
int
rem
=
remaining
;
if
(
ourList
.
modCount
!=
expectedModCount
)
{
throw
new
ConcurrentModificationException
();
}
if
(
rem
==
0
)
{
throw
new
NoSuchElementException
();
}
remaining
=
rem
-
1
;
return
(
E
)
ourList
.
array
[
removalIndex
=
ourList
.
size
-
rem
];
}
public
void
remove
()
{
Object
[]
a
=
array
;
int
removalIdx
=
removalIndex
;
if
(
modCount
!=
expectedModCount
)
{
throw
new
ConcurrentModificationException
();
}
if
(
removalIdx
0
)
{
throw