1. 概述

在本文中,我们将深入探讨抽象工厂模式(Abstract Factory Pattern)的设计思想与实现方式。

《设计模式:可复用面向对象软件的基础》一书中对抽象工厂模式的定义是:

“提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。”

换句话说,抽象工厂模式允许我们创建遵循某种通用结构的对象家族,同时隐藏具体实现细节。

JDK 中就有一个典型的抽象工厂模式应用示例 —— javax.xml.parsers.DocumentBuilderFactory 类中的 newInstance() 方法。

2. 抽象工厂模式示例

接下来我们通过一个 Java 示例来演示抽象工厂模式的使用场景 —— 构建史前动物模型。

2.1 抽象产品类:Animal

首先定义一个抽象类 Animal 来表示动物的基本属性,包括其所属时代、类型和名称。此外还包含一个抽象方法 create(),由子类具体实现。

public abstract class Animal {
    AnimalType type;
    AnimalEra era;
    String name;

    Animal(AnimalType type, AnimalEra era, String name) {
        this.type = type;
        this.era = era;
        this.name = name;
    }

    abstract void create();
}

接着是两个具体的动物类别:

public class LandAnimal extends Animal {
    // 实现陆地动物的创建逻辑
}

public class SkyAnimal extends Animal {
    // 实现空中动物的创建逻辑
}

为了保持简洁,这里省略了具体的实现代码,完整代码可以参考 GitHub 仓库

2.2 抽象工厂接口:EraAnimalFactory

定义一个接口 EraAnimalFactory,用于声明创建不同动物的方法:

public interface EraAnimalFactory {

    LandAnimal makeLandAnimal();
    SkyAnimal makeSkyAnimal();
}

2.3 具体工厂类

分别实现不同地质年代的动物工厂:

public class CenozoicAnimalFactory implements EraAnimalFactory {
    // 创建新生代动物的具体实现
}

public class MesozoicAnimalFactory implements EraAnimalFactory {
    // 创建中生代动物的具体实现
}

2.4 工厂管理器:AnimalAbstractFactory

这个类负责根据配置选择合适的工厂,并生成对应的动物对象:

public class AnimalAbstractFactory {
    Animal animal;

    Animal createAnimal(AnimalType type) {
        AnimalEra era = getFromConfiguration();

        switch (era) {
            case MESOZOIC:
                animal = new MesozoicAnimalFactory().createAnimal(type);
                break;
            case CENOZOIC:
                animal = new CenozoicAnimalFactory().createAnimal(type);
                break;
        }

        return animal;
    }

    AnimalEra getFromConfiguration() {
        return AnimalEra.MESOZOIC; // 默认为中生代
    }
}

2.5 启动类:AbstractFactoryRunner

最后是一个简单的运行入口:

public class AbstractFactoryRunner {

    public static void main(String[] args) {
        new AnimalAbstractFactory().createAnimal(AnimalType.LAND);
    }
}

3. 使用场景 ✅

以下几种情况适合使用抽象工厂模式:

  • 客户端不需要关心对象的创建过程和组合方式。
  • 系统需要支持多个对象族,且这些对象族通常一起使用。
  • 需要基于运行时参数动态决定创建哪一类对象。

⚠️ 踩坑提醒:虽然抽象工厂模式非常适合创建预定义的对象族,但如果后续需要扩展新的对象类型,则必须修改 AbstractFactory 及其所有子类,这会带来一定的维护成本。

4. 总结

在这篇文章中,我们学习了抽象工厂模式的核心概念和典型应用场景。该模式非常适合构建具有统一结构但实现多样的对象体系。

如需查看完整代码,请访问 GitHub 示例项目: https://github.com/eugenp/tutorials/tree/master/patterns-modules/design-patterns-creational


原始标题:Abstract Factory Pattern in Java