工厂方法模式属于GoF23中设计模式之一,也是创建型设计模式,工厂方法模式的出现可以解决产品类别进行扩展或者缩减时需要修改工厂类的问题,工厂方法模式在一定程度上比简单工厂模式更加符合开闭原则。
工厂方法模式将工厂类进行了抽象,在简单工厂模式中,只有一个简单工厂类,该简单工厂类并没有向上形成任何抽象,而工厂方法模式通过对工厂本身提供一个抽象层,并在该抽象层中定义了一个抽象的产品创建方法,子类工厂通过实现该方法完成具体产品的创建,该抽象方法也就是工厂方法。
工厂方法模式将对象的创建延迟到子类中进行,客户端只需要依赖抽象级别的工厂和抽象的产品类,在需要创建某个具体的产品的时候,只需要传入一个具体工厂类对象到客户端中即可,借助工厂方法模式可以实现产品类别扩展和缩小的时候只需要新增代码,而对原有代码的改动是极小的,可以很好的符合开闭原则和单一职责原则(后续会说明为什么)。
工厂方法模式中包含如下几个角色:
package factorymethod;
public abstract class AbstractProduct {
public abstract String getProductUsage();
}
package factorymethod;
public class ConcreteProductA extends AbstractProduct {
@Override
public String getProductUsage() {
return "ConcreteProductA的使用方法";
}
}
package factorymethod;
public class ConcreteProductB extends AbstractProduct {
@Override
public String getProductUsage() {
return "ConcreteProductB的用法";
}
}
package factorymethod;
public abstract class AbstractFactory {
public abstract AbstractProduct createProduct();
}
package factorymethod;
public class ConcreteProductAFactory extends AbstractFactory {
@Override
public AbstractProduct createProduct() {
return new ConcreteProductA();
}
}
package factorymethod;
public class ConcreteProductBFactory extends AbstractFactory {
@Override
public AbstractProduct createProduct() {
return new ConcreteProductB();
}
}
package factorymethod;
public class Client {
public static void main(String[] args) {
AbstractFactory factory = new ConcreteProductAFactory();
AbstractProduct product = factory.createProduct();
System.out.println(product.getProductUsage());
}
}
在工厂方法模式中,新增一个产品类只需要两步,第一步实现抽象产品的方法,第二步实现抽象的工厂,完成具体产品的创建。无需改动现有的工厂类的代码,因此工厂方法模式很好的解决了简单工厂模式中,因此产品类扩展,而导致的工厂类代码的修改问题,很好的遵守了开闭原则。同时在工厂方法模式中一个工厂类只负责创建一个产品对象,而简单工厂模式中,简单工厂负责创建多个产品对象,因此工厂方法模式相较于简单工厂模式更遵守单一职责原则。
工厂方法模式的缺点就是每次增加一个产品类就需要增加一个对应的工厂类,如果产品类非常多,那么工厂类也会随之变多,这会导致类的维护变得困难,导致代码量变多。