【工厂方法模式的定义】:
定义一个用于创建对象的接口,让子类决定实例化哪个类
【工厂方法模式的使用场景】:
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
【工厂方法模式的通用模式代码】:
抽象产品类:
public abstract class Product {
/**
*产品.
public abstract void ethod();
}
具体产品A:
public class ConcreteProductA extends Product {
@Override
public void method(){
System.out.println("我是具体产品A");
}
}
具体产品B:
public class ConcreteProductB extends Product {
@Override
public void method(){
System.out.println("我是具体产品B");
}
}
抽象工厂类:
public abstract class Factory {
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
* @return 具体的产品对象
*/
public abstract Product createProduct():
}
具体工厂类:
public ConcreteFactory extends Factory {
@Overide
public Product createProduct() {
return new ConcreteProductA();
//return new ConcreteProductB();
}
}
客户类:
public class Client {
public static void main(String[] args) {
Factory factory = new ConcreteFactory();
Product p = factory.creatProduct();
p.method();
}
}
这里的几个角色都很简单,主要分为四大模块:
- 抽象工厂,其为工厂方法模式的核心;
- 具体工厂,其实现了具体的业务逻辑;
- 抽象产品,是工厂方法模式所创建的产品的父类;
- 具体产品,为实现抽象产品的某个具体产品的对象。
上述的代码中我们在Client类中构造了一个工厂对象,并通过其生产了一个产品对象,这里我们得到的产品对象是ConcreteProductA的实例,如果想得到ConcreteProductB的实例,更改ConcreteFactory中的逻辑即可:
public ConcreteFactory extends Factory {
@Overide
public Product createProduct() {
//return new ConcreteProductA();
return new ConcreteProductB();
}
}
这种方式比较觉,需要哪一个产品就生产哪一个,有时候也可以利用反射的方式更简洁地来生产具体产品对象,此时,需要在工厂方法的参数列表中传入一个Class类来决定是哪一个产品类:
public abstract class Factory {
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
* @return 具体的产品对象
*/
public abstract <T extends Product> T createProduct(Class<T> clz):
}
具体工厂类:(通过反射获取类的实例)
public ConcreteFactory extends Factory {
@Overide
public <T extends Product> T createProduct(Class<T> clz) {
Product p = null;
try {
p = (Product) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T)p;
}
}
Client:
public class Client {
public static void main(String[] args) {
Factory factory = new ConcreteFactory();
Product p = factory.createProduct(ConcreateProductB.class);
p.method();
}
}
【Android源码中的工厂方法模式实现】
以List和Set为例,List和Set都继承于Collection接口,而Collection接口继承于Iterable接口,Iterable接口很简单,就一个iterator方法。
public iterface Iterable<T> {
Iterator<T> iterator();
}
这意味着List和Set接口也会继承该方法,平时比较常用的两个间接实现类ArrayList和HasSet中iterator方法的实现就是构造并返回一个迭代器对象。
public class ArrayList<E> extends AbstractList<E> impolements Cloenable, Serializeble, RandomAccess {
@Override public Iterator<E> iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator<E> {
private int remaining = size;
private int removalIndex = -1;
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) outList.array[removalIndex = ourList.size - rem];
}
public void remove() {
Object[] a = array;
int removalIdx = removalIndex;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (removalIdx < ) {
throw new IllegalStateException();
}
System.arraycopy(a, removalIdx + 1, a, removalIdx, remaining);
a[--size] = null; //Prevent memory leak
removalIndex = -1;
expectedModCount = ++modCount;
}
}
}
public class HasSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
{
@Override
public Iterator<E> iterator() {
return backingMap.keySet().iterator();
}
}
HashSet的iterator方法中会返回成员变量backingMap中对应HashSet对象元素的迭代器对象,最终返回的是KeySet中的一个迭代器对象:
public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneabl, Serializable
{
Iterator<K> newKeyIterator() {
return new KeyIterator();
}
private final class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
}
}
ArrayList和HasSet中的iterator方法其实就相当更进一于一个工厂方法,专为new对象而生,这里iterator方法是构造并返回一个具体的迭代器。当然,Java源码中对工厂方法的应用范例也不少,大家可以自己体会。Android中对工厂方法模式的应用更多:
Public class AActivity extends Activity {
@Overrid
protected void onCreate(Bundle savedInstanceState) {
super.onCreat(saveInstanceState);
setContentView(new LinearLayout(this));
}
}
这里构造一个纯属布局LinearLayout对象并设置为当前Activity的根而已,这段代码看亿再桂皮过了,实质上,onCreate方法就相当于一个工厂方法,为什么呢?因为我们知道LinearLayout是一个ViewGroup,而ViewGroup又继承于View,简单地说就是,所有控件都是View的子类,上面的代码中,我们的AActivity的onCreat方法中构造一个View对象,并设置为当前界面的ContentView返回给framework处理,如果现在又有一个BActivity,这里我们又在其onCreate方法中通过setContentView方法设置另外不同的View,这是不是就是一个工厂模式的结构呢?其实设计离我们非常近!