什么是工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。
结构
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
UML类图
代码理解
// 抽象产品类
abstract class Product {
public abstract void operation();
}
// 具体产品类A
class ConcreteProductA extends Product {
@Override
public void operation() {
System.out.println("具体产品A的操作");
}
}
// 具体产品类B
class ConcreteProductB extends Product {
@Override
public void operation() {
System.out.println("具体产品B的操作");
}
}
// 抽象工厂类
abstract class Creator {
public abstract Product factoryMethod();
public void operation() {
Product product = factoryMethod();
product.operation();
}
}
// 具体工厂类A
class ConcreteCreatorA extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}
// 具体工厂类B
class ConcreteCreatorB extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}
// 客户端代码
public class FactoryMethodPattern {
public static void main(String[] args) {
Creator creatorA = new ConcreteCreatorA();
creatorA.operation();
Creator creatorB = new ConcreteCreatorB();
creatorB.operation();
}
}
优点:
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
- 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点:
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
案例分析
JDK源码解析-Collection.iterator()方法
使用了工厂方法模式,将ArrayList、LInkedList、Vetor等Collection接口实现类看作为同等级产品的具体工厂。
- 抽象工厂类:Collection接口可以被视为一个抽象工厂类,它定义了创建对象的方法iterator(),该方法返回一个Iterator对象。
- 具体工厂类:ArrayList类实现了Collection接口,因此它是一个具体的工厂类。ArrayList类中的iterator()方法负责创建一个具体的迭代器对象。
- 抽象商品类:Iterator接口是一个抽象商品类,它定义了遍历集合元素的方法,如hasNext()和next()。
- 具体商品类:ArrayList类中的内部类Iter(在实际的ArrayList实现中,这个内部类可能有不同的名称,如Itr)是Iterator接口的一个具体实现,它是具体的商品类。这个内部类实现了Iterator接口中定义的方法,并提供了遍历ArrayList元素的具体逻辑。