三种工厂设计模式

在面向对象编程中,设计模式是经过反复验证的代码设计经验总结,能帮助我们写出更具可读性、可扩展性和可维护性的代码。工厂模式作为创建型设计模式的核心成员,主要用于封装对象的创建过程,降低代码耦合度。本文将详细拆解简单工厂模式工厂方法模式抽象工厂模式三种常见实现,结合实例剖析其核心逻辑、适用场景及各自优劣。

目录

一、核心思想:工厂模式解决了什么问题?

二、三种工厂模式的具体实现

[1. 简单工厂模式(Simple Factory Pattern)](#1. 简单工厂模式(Simple Factory Pattern))

核心定义

代码实现

优缺点分析

[2. 工厂方法模式(Factory Method Pattern)](#2. 工厂方法模式(Factory Method Pattern))

核心定义

代码实现

扩展场景:新增平板产品

优缺点分析

[3. 抽象工厂模式(Abstract Factory Pattern)](#3. 抽象工厂模式(Abstract Factory Pattern))

核心定义

代码实现

优缺点分析

三、三种工厂模式的对比与选型建议

四、总结


一、核心思想:工厂模式解决了什么问题?

在日常开发中,直接通过**new** 关键字创建对象会导致代码强耦合------一旦对象的构造逻辑变化、类名修改,所有使用该对象的地方都需要逐一修改。工厂模式的核心思路的是:将对象的创建与使用分离,由专门的"工厂类"负责对象的创建,调用者只需通过工厂获取对象,无需关心创建的细节(如构造参数、依赖关系、具体实现类等)。

这种思想就像现实中的工厂:我们想要一台手机,无需自己动手组装,只需从手机工厂购买即可,工厂负责零部件采购、组装、检测等全流程。代码中引入工厂后,调用者与具体产品类解耦,后续替换产品实现、扩展新产品时,只需修改工厂逻辑,无需改动调用代码。

二、三种工厂模式的具体实现

下面我们以"电子产品生产"为场景,分别实现三种工厂模式,对比其差异。场景需求:需生产手机、电脑两种产品,后续可能扩展平板等新产品,不同产品的生产流程(构造逻辑)不同。

1. 简单工厂模式(Simple Factory Pattern)

核心定义

简单工厂模式又称"静态工厂模式",由一个工厂类根据传入的参数,动态决定创建哪一种产品类的实例。它只有一个工厂类,负责所有产品的创建,产品类需继承自同一个父类或实现同一个接口。

代码实现
java 复制代码
// 产品接口(统一产品规范)
public interface ElectronicProduct {
    void produce(); // 生产方法
}

// 具体产品1:手机
public class Phone implements ElectronicProduct {
    @Override
    public void produce() {
        System.out.println("生产一部智能手机");
    }
}

// 具体产品2:电脑
public class Computer implements ElectronicProduct {
    @Override
    public void produce() {
        System.out.println("生产一台笔记本电脑");
    }
}

// 简单工厂类(核心)
public class ElectronicFactory {
    // 静态方法,根据参数创建对应产品
    public static ElectronicProduct createProduct(String type) {
        switch (type) {
            case "phone":
                return new Phone();
            case "computer":
                return new Computer();
            default:
                throw new IllegalArgumentException("未知产品类型");
        }
    }
}

// 调用者使用
public class Client {
    public static void main(String[] args) {
        // 无需new具体产品,通过工厂获取
        ElectronicProduct phone = ElectronicFactory.createProduct("phone");
        phone.produce(); // 输出:生产一部智能手机
        
        ElectronicProduct computer = ElectronicFactory.createProduct("computer");
        computer.produce(); // 输出:生产一台笔记本电脑
    }
}
优缺点分析

优点:实现简单,逻辑清晰,调用者无需关心产品创建细节,仅需传入参数即可获取对象,初步实现了解耦。

缺点:违背"开闭原则"(对扩展开放,对修改关闭)。若需新增平板产品,必须修改工厂类中的switch逻辑,导致工厂类职责过重,后续产品越多,工厂类越难维护;同时,静态方法无法被继承和重写,灵活性较差。

适用场景:产品种类较少、变化不频繁的简单场景,如小型工具类创建、配置项实例化等。

2. 工厂方法模式(Factory Method Pattern)

核心定义

为解决简单工厂模式的"开闭原则"问题,工厂方法模式将单一工厂拆分为"工厂接口+具体工厂":定义一个创建产品的工厂接口,每个具体产品对应一个具体工厂,由具体工厂负责创建对应的产品实例。调用者通过实例化具体工厂,获取对应产品。

这种设计让工厂类也遵循"开闭原则"------新增产品时,无需修改现有工厂代码,只需新增一个具体产品类和对应的具体工厂类即可。

代码实现
java 复制代码
// 产品接口(与简单工厂一致)
public interface ElectronicProduct {
    void produce();
}

// 具体产品1:手机(与简单工厂一致)
public class Phone implements ElectronicProduct {
    @Override
    public void produce() {
        System.out.println("生产一部智能手机");
    }
}

// 具体产品2:电脑(与简单工厂一致)
public class Computer implements ElectronicProduct {
    @Override
    public void produce() {
        System.out.println("生产一台笔记本电脑");
    }
}

// 工厂接口(定义工厂规范)
public interface ProductFactory {
    ElectronicProduct createProduct(); // 工厂方法,创建产品
}

// 具体工厂1:手机工厂(负责生产手机)
public class PhoneFactory implements ProductFactory {
    @Override
    public ElectronicProduct createProduct() {
        return new Phone();
    }
}

// 具体工厂2:电脑工厂(负责生产电脑)
public class ComputerFactory implements ProductFactory {
    @Override
    public ElectronicProduct createProduct() {
        return new Computer();
    }
}

// 调用者使用
public class Client {
    public static void main(String[] args) {
        // 实例化对应工厂,获取产品
        ProductFactory phoneFactory = new PhoneFactory();
        ElectronicProduct phone = phoneFactory.createProduct();
        phone.produce();
        
        ProductFactory computerFactory = new ComputerFactory();
        ElectronicProduct computer = computerFactory.createProduct();
        computer.produce();
    }
}
扩展场景:新增平板产品

若需新增平板产品,仅需新增两个类,无需修改现有代码:

java 复制代码
// 新增具体产品:平板
public class Tablet implements ElectronicProduct {
    @Override
    public void produce() {
        System.out.println("生产一台平板电脑");
    }
}

// 新增具体工厂:平板工厂
public class TabletFactory implements ProductFactory {
    @Override
    public ElectronicProduct createProduct() {
        return new Tablet();
    }
}
优缺点分析

优点:严格遵循"开闭原则",扩展灵活;每个工厂只负责一种产品的创建,职责单一,代码可维护性强;工厂接口可被继承重写,灵活性优于简单工厂。

缺点:产品与工厂一一对应,新增产品时需同时新增产品类和工厂类,导致类数量激增("类爆炸"问题);调用者需明确知道具体工厂类,增加了使用成本。

适用场景:产品种类较多、变化频繁,且需要严格遵循开闭原则的场景,如框架插件开发、多产品体系的业务模块等。

3. 抽象工厂模式(Abstract Factory Pattern)

核心定义

当产品分为"产品族"和"产品等级结构"时,工厂方法模式难以应对,此时需要抽象工厂模式。抽象工厂模式定义一个工厂接口,用于创建一系列相关或相互依赖的产品(一个产品族),每个具体工厂实现该接口,负责创建对应产品族的所有产品。

关键概念:

  • 产品族:同一品牌、同一风格的一系列产品,如"苹果产品族"包含苹果手机、苹果电脑、苹果平板;"华为产品族"包含华为手机、华为电脑、华为平板。

  • 产品等级结构:同一类型、不同品牌的产品,如手机等级结构包含苹果手机、华为手机、小米手机。

抽象工厂模式的核心是"生产产品族",而非单一产品。

代码实现

场景升级:需生产苹果、华为两个产品族,每个产品族包含手机、电脑两种产品。

java 复制代码
// 产品等级结构1:手机接口
public interface Phone {
    void produce();
}

// 产品等级结构2:电脑接口
public interface Computer {
    void produce();
}

// 苹果产品族:苹果手机(属于手机等级结构)
public class IPhone implements Phone {
    @Override
    public void produce() {
        System.out.println("生产苹果手机");
    }
}

// 苹果产品族:苹果电脑(属于电脑等级结构)
public class Mac implements Computer {
    @Override
    public void produce() {
        System.out.println("生产苹果电脑");
    }
}

// 华为产品族:华为手机(属于手机等级结构)
public class HuaweiPhone implements Phone {
    @Override
    public void produce() {
        System.out.println("生产华为手机");
    }
}

// 华为产品族:华为电脑(属于电脑等级结构)
public class HuaweiComputer implements Computer {
    @Override
    public void produce() {
        System.out.println("生产华为电脑");
    }
}

// 抽象工厂接口(定义产品族的创建规范)
public interface AbstractFactory {
    Phone createPhone(); // 生产手机
    Computer createComputer(); // 生产电脑
}

// 具体工厂1:苹果工厂(生产苹果产品族)
public class AppleFactory implements AbstractFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }

    @Override
    public Computer createComputer() {
        return new Mac();
    }
}

// 具体工厂2:华为工厂(生产华为产品族)
public class HuaweiFactory implements AbstractFactory {
    @Override
    public Phone createPhone() {
        return new HuaweiPhone();
    }

    @Override
    public Computer createComputer() {
        return new HuaweiComputer();
    }
}

// 调用者使用
public class Client {
    public static void main(String[] args) {
        // 生产苹果产品族
        AbstractFactory appleFactory = new AppleFactory();
        appleFactory.createPhone().produce(); // 输出:生产苹果手机
        appleFactory.createComputer().produce(); // 输出:生产苹果电脑
        
        // 生产华为产品族
        AbstractFactory huaweiFactory = new HuaweiFactory();
        huaweiFactory.createPhone().produce(); // 输出:生产华为手机
        huaweiFactory.createComputer().produce(); // 输出:生产华为电脑
    }
}
优缺点分析

优点:能高效管理产品族,确保同一产品族的产品相互兼容;新增产品族时,仅需新增一个具体工厂类,无需修改现有代码,符合开闭原则;封装性强,调用者无需关心产品的具体实现。

缺点:扩展产品等级结构困难(如新增"平板"产品等级),需修改抽象工厂接口及所有具体工厂类,违背开闭原则;类结构复杂,理解成本较高。

适用场景:存在多个产品族,且产品族内的产品相互依赖、需要统一管理的场景,如跨平台组件开发(Windows/Mac 组件族)、品牌化产品体系设计等。

三、三种工厂模式的对比与选型建议

模式类型 核心特点 开闭原则 类数量 适用场景
简单工厂 单一工厂生产所有产品 不遵循 少(1个工厂+N个产品) 产品少、变化少
工厂方法 产品与工厂一一对应 遵循 多(N个工厂+N个产品) 产品多、变化多,无产品族
抽象工厂 工厂生产产品族 产品族扩展遵循,产品等级扩展不遵循 中(M个工厂+M*N个产品) 存在多个产品族,需统一管理

四、总结

三种工厂模式本质都是"封装对象创建",核心差异在于工厂的职责范围和扩展方式:

  1. 简单工厂是"入门级"实现,适合简单场景,牺牲开闭原则换取简洁性;

  2. 工厂方法是"精细化"实现,通过一对一工厂拆分,遵循开闭原则,解决简单工厂的扩展问题;

  3. 抽象工厂是"体系化"实现,针对产品族场景,平衡了产品族扩展与产品等级扩展的需求。

实际开发中,无需盲目追求复杂模式,应根据业务场景选型:小型项目用简单工厂快速落地,中大型项目若产品独立可选用工厂方法,若存在产品族则用抽象工厂。核心目标是通过合理的封装,让代码更易维护、更具扩展性。

相关推荐
嗯嗯**2 小时前
Neo4j学习3:Java连接图库并执行CQL
java·学习·spring·neo4j·图数据库·驱动·cql
洛阳纸贵2 小时前
JAVA高级工程师--Springboot集成ES、MySQL同步ES的方案、ES分片副本、文档及分片规划
java·spring boot·elasticsearch
阿猿收手吧!2 小时前
【C++】C++原子类型隐式转换解析
java·c++
追逐梦想的张小年2 小时前
JUC编程02
java·idea
我是一只小小鱼~2 小时前
JAVA 使用spring boot 搭建WebAPI项目
java·数据库·spring boot
量子炒饭大师2 小时前
【C++入门】—— 【什么时候需要用到深拷贝】C++的类中何时需要用到深拷贝?保姆级别带你罗列所有可能!
java·c++·dubbo·深拷贝
小信丶2 小时前
@EnableMethodCache 注解详解:原理、应用场景与示例代码
java·spring boot·后端·spring
坊钰2 小时前
【Rabbit MQ】Rabbit MQ 的结构详解,传输机制!!!
java·rabbitmq