一、概述
工厂方法模式是在简单工厂模式的基础上进行的,它去掉了简单工厂模式中静态方法的静态属性,让它可以被子类继承重写。
这样做的好处就是可以避免在工厂类不可用时,系统遭受影响,使用这种方式,可以让不同的工厂子类自己创建对应的实例对象。
如果需要扩展只需按照规则扩展,不需要修改任何已有的代码,附和开闭原则。
二、模块
- AbstractProduct:抽象产品类,用来定义所有具体产品的规范,是所有具体产品的公共父类。
- Drinks 类和Water类:具体产品类,要实例化的类。
- AbstractFactory类:抽象工厂类,是工厂方法模式的核心,所有具体工厂类都要继承它,然后创建对象。
- WaterFactory类和 DrinksFactory类:具体工厂类,用来创建具体产品的对象。
三、示例
假如有一个酒水加工厂,主要生产酒、饮料、矿泉水,这个过程我们就可以使用工厂方法模式。
四、代码
第一步:创建抽象产品类,以及具体产品类
/**
* 抽象产品类
*/
public abstract class AbstractProduct {
public abstract void getProduct();
}
/**
* 具体产品类
*/
public class Drinks extends AbstractProduct {
@Override
public void getProduct() {
System.out.println("科技与狠活饮料");
}
}
/*
* 具体产品类
*/
public class Water extends AbstractProduct {
@Override
public void getProduct() {
System.out.println("科技与狠活矿泉水");
}
}
第二步:创建抽象工厂类,以及具体工厂类
/**
* 抽象工厂类
*/
public abstract class AbstractFactory {
public abstract AbstractProduct createProduct();
}
/**
* 具体工厂类
*/
public class DrinksFactory extends AbstractFactory {
@Override
public AbstractProduct createProduct() {
return new Drinks();
}
}
/**
* 具体工厂类
*/
public class WaterFactory extends AbstractFactory {
@Override
public AbstractProduct createProduct() {
return new Water();
}
}
第三步:测试
/**
* 测试
*/
public class FactoryMethodDemo {
public static void main(String[] args) {
// 创建饮料对象
DrinksFactory drinksFactory = new DrinksFactory();
AbstractProduct product = drinksFactory.createProduct();
product.getProduct();
// 创建矿泉水对象
WaterFactory waterFactory = new WaterFactory();
AbstractProduct waterFactoryProduct = waterFactory.createProduct();
waterFactoryProduct.getProduct();
}
}
五、思考与总结
在扩展新产品时使用工厂方法模式遵守了开闭原则。
优点:
- 在创建对象时,客户端仅需要根据对应产品的工厂类就可以得到对应的产品类,无需知晓内部的创建过程。
- 提高了系统整体的灵活性,实现了解耦,即在进行扩展时只需继承抽象工厂以及抽象产品。
缺点:
- 系统中类的个数增加,一定程度上增加了复杂度以及理解难度和抽象性。
- 工厂方法本身利用了抽象 , 该模式中会引入抽象层 , 如果要动态创建产品类 , 还要引入反射技术 ;