工厂方法的解题思路是采用无为而治的方式,即自己不知道具体如何实现,把它延迟到子类实现。
1、定义
定义一个用于创建对象的接口,让子类决定实例化哪个具体类。
2、使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
3、UML图
- Product:抽象产品。
- ConcreteProduct:具体产品
- Factory:创建器,抽象工厂,申明创建Product的工厂方法。
- ConcreteFactory:具体工厂,实现具体的业务逻辑。
4、示例代码
public abstract class Product {
}
public class ConcreteProduct extends Product {
}
public abstract class Factory {
public abstract Product createProduct();
//有时在一些方法中需要调用工厂方法来获取 Product 对象
public void someOperation() {
Product product = createProduct();
}
}
public class ConcreteFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreteProduct();
}
}
对于createProduct()方法,需要哪个产品就生产哪个产品,但有时也可以使用反射的方式更简洁地生产具体的产品对象。
反射实现:
public abstract class Factory {
public abstract <T extends Product> T createProduct(Class<T> cls);
}
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> cls) {
Product p = null;
try {
p = (Product) Class.forName(cls.getName()).newInstance();
} catch(Exception e) {
e.printStackTrace();
}
return (T) p;
}
}
5、简单工厂/静态工厂
抽象出抽象工厂类 Factory 来,通常的情况是有多个不同的具体工厂实现。以上只是实现了一个具体工厂concreteFactory,但通常一般还可能定义ConcreteFactoryA,ConcreteFactoryB …等,以产生不同的产品。这种我们称为多工厂方法模式。
如果我们确定我们的工厂类只有一个的时候,可以将其简化掉,将对应的工厂方法改为静态方法,那这种情况就变成了简单工厂/静态工厂了,它是工厂方法的一个弱化版本。
public class Factory {
public static Product createProduct() {
return new ConcreteProduct();
}
}
6、Java源码中的实现
java中的 List , Set 就应用了工厂方法模式来获取 Iterator。它们都实现了 Iterable 接口,来生产具体的 Iterator。
1、定义生产 Iterator 的接口
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
//...
}
2、 ArrayList 生产具体的 Iterator 的实现
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
//ArrayList 生产具体的 Iterator 的实现
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
//...
}
//...
}
3、HashSet生产具体的 Iterator 的实现
public class HashSet<E> extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
public Iterator<E> iterator() {
return map.keySet().iterator();
}
}