工厂模式
工厂模式:原理、类型与实践应用详解
一、工厂模式的核心定义与价值
工厂模式是创建型设计模式的核心代表,其核心思想是 “将对象的创建与使用分离”—— 通过专门的 “工厂类” 负责对象的实例化,调用方无需关心对象创建的细节(如构造函数参数、依赖关系、实例化逻辑),只需通过工厂获取所需对象即可。
它的核心价值体现在三个方面:
-
降低耦合:调用方无需依赖具体类的构造逻辑,若后续类的实现变更(如新增参数、替换子类),只需修改工厂,无需修改所有调用处;
-
统一管理:对象创建的逻辑(如权限控制、单例判断、初始化配置)集中在工厂,便于维护和扩展;
-
符合开闭原则:新增产品类型时,无需修改现有工厂核心逻辑(部分模式需扩展),只需新增对应工厂或产品类。
二、工厂模式的三种核心类型与实现
根据复杂度和适用场景,工厂模式分为简单工厂、工厂方法、抽象工厂三类,三者的核心差异在于 “工厂与产品的对应关系” 和 “扩展灵活性”。
1. 简单工厂模式(Simple Factory):单一工厂生产多类产品
-
原理:定义一个 “万能工厂类”,通过传入参数(如字符串、枚举),由工厂判断并创建对应产品对象。
-
结构:包含 3 个角色:
-
抽象产品(Product):定义所有产品的统一接口(如 “手机” 接口,包含 “打电话” 方法);
-
具体产品(ConcreteProduct):实现抽象产品接口的具体类(如 “苹果手机”“华为手机”);
-
简单工厂(SimpleFactory):包含静态或实例方法,根据参数创建对应具体产品实例。
-
-
代码示例(Java):
// 1. 抽象产品:手机接口
public interface Phone {
void call(); // 统一方法
}
// 2. 具体产品1:苹果手机
public class IPhone implements Phone {
@Override
public void call() {
System.out.println("用苹果手机打电话");
}
}
// 3. 具体产品2:华为手机
public class HuaweiPhone implements Phone {
@Override
public void call() {
System.out.println("用华为手机打电话");
}
}
// 4. 简单工厂:生产手机的工厂
public class PhoneFactory {
// 根据参数创建对应产品
public static Phone createPhone(String type) {
switch (type) {
case "iphone":
return new IPhone();
case "huawei":
return new HuaweiPhone();
default:
throw new IllegalArgumentException("未知手机类型");
}
}
}
// 调用方使用
public class Client {
public static void main(String\[] args) {
// 无需new具体类,通过工厂获取
Phone iphone = PhoneFactory.createPhone("iphone");
iphone.call(); // 输出:用苹果手机打电话
}
}
-
适用场景:产品类型较少且稳定(如仅 2-3 类产品),无需频繁新增;适合简单业务场景(如工具类创建、配置化实例化)。
-
缺点:违背 “开闭原则”—— 新增产品(如 “小米手机”)时,需修改工厂的
switch逻辑,导致工厂代码不断膨胀。
2. 工厂方法模式(Factory Method):一个工厂生产一类产品
-
原理:为解决简单工厂的 “开闭原则” 问题,将 “单一工厂” 拆分为 “多个工厂”—— 每个具体产品对应一个专属工厂,抽象出 “工厂接口”,调用方通过具体工厂获取对应产品。
-
结构:包含 4 个角色:
-
抽象产品(Product):同简单工厂,定义产品统一接口;
-
具体产品(ConcreteProduct):同简单工厂,实现抽象产品;
-
抽象工厂(AbstractFactory):定义工厂的统一接口(仅含 “创建产品” 方法);
-
具体工厂(ConcreteFactory):实现抽象工厂,每个具体工厂仅创建一种具体产品(如 “苹果工厂” 只产 “苹果手机”)。
-
-
代码示例(Java):
// 1. 抽象产品:手机接口(同简单工厂)
public interface Phone {
void call();
}
// 2. 具体产品:苹果手机、华为手机(同简单工厂)
public class IPhone implements Phone { ... }
public class HuaweiPhone implements Phone { ... }
// 3. 抽象工厂:手机工厂接口
public interface PhoneFactory {
Phone createPhone(); // 仅定义创建方法,不包含判断逻辑
}
// 4. 具体工厂1:苹果工厂(只产苹果手机)
public class IPhoneFactory implements PhoneFactory {
@Override
public Phone createPhone() {
return new IPhone();
}
}
// 5. 具体工厂2:华为工厂(只产华为手机)
public class HuaweiFactory implements PhoneFactory {
@Override
public Phone createPhone() {
return new HuaweiPhone();
}
}
// 调用方使用
public class Client {
public static void main(String\[] args) {
// 1. 创建对应工厂
PhoneFactory factory = new IPhoneFactory();
// 2. 通过工厂获取产品
Phone iphone = factory.createPhone();
iphone.call(); // 输出:用苹果手机打电话
}
}
-
适用场景:产品类型较多且需频繁新增(如电商系统的 “商品工厂”,新增 “服装”“家电” 时只需加 “服装工厂”“家电工厂”);适合复杂业务中 “产品与工厂一一对应” 的场景。
-
优点:符合 “开闭原则”—— 新增产品时,只需新增 “具体产品类” 和 “具体工厂类”,无需修改现有代码;
-
缺点:类数量膨胀 —— 每新增一个产品,需同步新增一个工厂,导致系统中类的数量翻倍。
3. 抽象工厂模式(Abstract Factory):一个工厂生产多类关联产品
-
原理:当产品存在 “产品族”(一组关联产品,如 “苹果手机 + 苹果耳机” 属于苹果产品族,“华为手机 + 华为耳机” 属于华为产品族)时,抽象工厂模式允许一个具体工厂生产一整个产品族的产品,而非单一产品。
-
结构:包含 4 个角色(核心差异是 “抽象产品” 和 “抽象工厂” 的扩展):
-
抽象产品族(多个抽象产品):如 “手机接口”“耳机接口”,同属 “电子设备” 产品族;
-
具体产品族(多个具体产品):如 “苹果手机 + 苹果耳机”“华为手机 + 华为耳机”,每个具体产品族对应一个品牌;
-
抽象工厂(AbstractFactory):定义生产 “产品族中所有产品” 的方法(如 “创建手机”“创建耳机”);具体工厂(ConcreteFactory):实现抽象工厂,每个具体工厂生产一整个产品族(如 “苹果工厂” 产 “苹果手机 + 苹果耳机”)。
-
-
代码示例(Java):
// 1. 抽象产品1:手机接口
public interface Phone {
void call();
}
// 2. 抽象产品2:耳机接口(产品族的另一成员)
public interface Earphone {
void playMusic();
}
// 3. 具体产品族1:苹果系列
public class IPhone implements Phone {
@Override
public void call() { System.out.println("苹果手机打电话"); }
}
public class AirPods implements Earphone {
@Override
public void playMusic() { System.out.println("AirPods播放音乐"); }
}
// 4. 具体产品族2:华为系列
public class HuaweiPhone implements Phone {
@Override
public void call() { System.out.println("华为手机打电话"); }
}
public class HuaweiEarphone implements Earphone {
@Override
public void playMusic() { System.out.println("华为耳机播放音乐"); }
}
// 5. 抽象工厂:电子设备工厂(定义生产产品族的方法)
public interface ElectronicFactory {
Phone createPhone(); // 生产手机
Earphone createEarphone(); // 生产耳机
}
// 6. 具体工厂1:苹果工厂(生产苹果产品族)
public class AppleFactory implements ElectronicFactory {
@Override
public Phone createPhone() { return new IPhone(); }
@Override
public Earphone createEarphone() { return new AirPods(); }
}
// 7. 具体工厂2:华为工厂(生产华为产品族)
public class HuaweiFactory implements ElectronicFactory {
@Override
public Phone createPhone() { return new HuaweiPhone(); }
@Override
public Earphone createEarphone() { return new HuaweiEarphone(); }
}
// 调用方使用(获取一整个产品族)
public class Client {
public static void main(String\[] args) {
// 选择苹果工厂,获取苹果产品族
ElectronicFactory appleFactory = new AppleFactory();
Phone iphone = appleFactory.createPhone();
Earphone airPods = appleFactory.createEarphone();
iphone.call(); // 苹果手机打电话
airPods.playMusic(); // AirPods播放音乐
}
}
-
适用场景:存在明确 “产品族” 且需保证产品间关联性的场景(如框架开发中的 “组件套装”、电商系统的 “品牌专属配件”);适合需要统一管理 “多类关联产品创建” 的场景(如保证 “苹果手机” 只能搭配 “苹果耳机”)。
-
优点:强关联产品的创建逻辑集中,避免调用方误用不匹配的产品(如不会出现 “苹果手机 + 华为耳机” 的组合,除非新增对应工厂);
-
缺点:扩展产品族困难 —— 若新增产品族成员(如 “平板”),需修改所有抽象工厂和具体工厂的接口,违背 “开闭原则”。
三、三种工厂模式的核心差异对比
| 维度 | 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|---|
| 工厂与产品关系 | 1 个工厂生产 N 类产品 | 1 个工厂生产 1 类产品 | 1 个工厂生产 1 组关联产品(产品族) |
| 开闭原则符合性 | 不符合(新增产品改工厂) | 符合(新增产品加工厂) | 部分符合(新增产品族符合,新增产品成员不符合) |
| 类数量 | 少(1 工厂 + N 产品) | 中(N 工厂 + N 产品) | 多(N 工厂 + M*N 产品,M 为产品族成员数) |
| 适用场景 | 产品少且稳定 | 产品多且需频繁新增 | 存在明确产品族且需关联生产 |
四、工厂模式的实际应用场景
-
框架开发:如 Spring 框架的
BeanFactory,通过工厂统一创建和管理 Bean 对象,调用方无需关心 Bean 的依赖注入和初始化逻辑; -
工具类封装:如日志框架(Log4j、SLF4J),通过工厂根据配置创建不同的日志对象(控制台日志、文件日志);
-
跨平台组件:如 GUI 框架(Swing、AWT),通过抽象工厂创建不同操作系统的组件(Windows 按钮、Mac 按钮);
-
业务系统:如电商系统的 “支付工厂”—— 根据支付类型(微信、支付宝)创建对应支付对象,新增支付方式时只需扩展工厂。

浙公网安备 33010602011771号