设计模式:工厂模式 (简单工厂、工厂方法、抽象工厂) 案例详解

目录

一、引言:为什么需要工厂模式?

二、简单工厂模式(Simple Factory)

1. 核心思想

2. 代码示例

3. 优点与缺点

4. 适用场景

三、工厂方法模式(Factory Method)

1. 核心思想

2. 代码示例

3. 优点与缺点

4. 适用场景

四、抽象工厂模式(Abstract Factory)

1. 核心思想

2. 代码示例

3. 优点与缺点

4. 适用场景

五、对比与选择建议

六、进阶技巧与注意事项

七、总结


一、引言:为什么需要工厂模式?

在软件开发中,对象的创建逻辑如果直接散落在代码中,会带来两大问题:

  1. 代码冗余:重复的 new 操作散布在各处。
  2. 维护困难:若创建逻辑需要修改(如替换实现类),需到处修改代码。

工厂模式(Factory Pattern)通过封装对象创建过程,将对象的实例化与业务逻辑分离,解决了上述问题。它是 Java 开发中最常用的设计模式之一,尤其在框架设计(如 Spring)和复杂系统开发中广泛应用。

二、简单工厂模式(Simple Factory)

1. 核心思想

通过一个静态工厂类,根据传入的参数(如字符串、枚举)决定创建哪种具体对象。所有对象的创建逻辑集中在一个类中。

2. 代码示例

以“汽车制造”为例:

// 抽象产品接口
public interface Car {
    void drive();
}

// 具体产品:跑车
public class SportsCar implements Car {
    @Override
    public void drive() {
        System.out.println("Driving a sports car!");
    }
}

// 具体产品:SUV
public class SUVCar implements Car {
    @Override
    public void drive() {
        System.out.println("Driving an suv7ultra!");
    }
}

// 简单工厂类
public class SimpleCarFactory {
    public static Car createCar(String type) {
        if ("sports".equalsIgnoreCase(type)) {
            return new SportsCar();
        } else if ("suv".equalsIgnoreCase(type)) {
            return new SUVCar();
        }
        throw new IllegalArgumentException("Unknown car type: " + type);
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        Car myCar = SimpleCarFactory.createCar("sports");
        myCar.drive(); // 输出:Driving a sports car!
    }
}
3. 优点与缺点
  • 优点
    • ✅ 简单易用,适合产品类型少的场景(如配置读取、日志记录)。
    • ✅ 客户端无需关心创建细节,只需传入参数。
  • 缺点
    • ❌ 违反开闭原则:新增产品类型需修改工厂类(如增加“电动车”需改动 createCar 方法)。
    • ❌ 工厂类职责过重,代码集中度高。
4. 适用场景
  • 产品类型固定且较少(如数据库驱动管理器)。
  • 快速实现原型或小型项目。

三、工厂方法模式(Factory Method)

1. 核心思想

定义一个抽象工厂接口,由子类实现具体对象的创建逻辑。将对象的创建延迟到子类,符合开闭原则

2. 代码示例

延续“汽车制造”案例:

// 抽象工厂接口
public interface CarFactory {
    Car createCar();
}

// 具体工厂:跑车工厂
public class SportsCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new SportsCar();
    }
}

// 具体工厂:SUV工厂
public class SUVCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new SUVCar();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        CarFactory factory = new SportsCarFactory();
        Car car = factory.createCar();
        car.drive(); // 输出:Driving a sports car!
    }
}
3. 优点与缺点
  • 优点
    • ✅ 符合开闭原则,新增产品只需添加新工厂类(如增加“电动车工厂”无需修改现有代码)。
    • ✅ 解耦客户端与具体类,客户端仅需依赖抽象工厂接口。
  • 缺点
    • ❌ 类数量增加(每个产品需对应一个工厂类)。
    • ❌ 若产品族较多,可能导致大量工厂类。
4. 适用场景
  • 产品类型较多且可能扩展(如游戏角色创建、UI 组件生成)。
  • 需要将对象创建逻辑分散到不同子类中。

四、抽象工厂模式(Abstract Factory)

1. 核心思想

提供一个抽象工厂接口,用于创建一组相关或依赖的对象(产品族)。例如,创建不同风格的 UI 组件(按钮、文本框)时,保证它们风格一致。

2. 代码示例

以“电子设备制造”为例:

// 抽象产品:手机
public interface Phone {
    void call();
}

// 抽象产品:耳机
public interface Headphones {
    void playMusic();
}

// 具体产品:小米手机
public class MiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("Calling with MiPhone...");
    }
}

// 具体产品:小米耳机
public class MiHeadphones implements Headphones {
    @Override
    public void playMusic() {
        System.out.println("Playing music with MiHeadphones...");
    }
}

// 抽象工厂接口
public interface DeviceFactory {
    Phone createPhone();
    Headphones createHeadphones();
}

// 具体工厂:小米工厂
public class MiDeviceFactory implements DeviceFactory {
    @Override
    public Phone createPhone() {
        return new MiPhone();
    }

    @Override
    public Headphones createHeadphones() {
        return new MiHeadphones();
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        DeviceFactory factory = new MiDeviceFactory();
        Phone phone = factory.createPhone();
        Headphones headphones = factory.createHeadphones();
        phone.call();
        headphones.playMusic();
    }
}
3. 优点与缺点
  • 优点
    • ✅ 保证产品族的一致性(如小米设备统一风格)。
    • ✅ 扩展产品族方便(如增加“苹果工厂”只需实现新工厂类)。
  • 缺点
    • ❌ 增加系统复杂度(需定义抽象工厂和所有产品接口)。
    • ❌ 不支持单独扩展某个产品(需修改所有相关产品接口)。
4. 适用场景
  • 需要创建一组关联产品(如跨平台 UI 组件、硬件设备套装)。
  • 强调产品族的兼容性和一致性(如 macOS 风格的按钮+文本框)。

五、对比与选择建议

模式目标扩展性代码复杂度适用场景
简单工厂集中创建单一产品差(需修改工厂类)产品少且固定(如配置读取)
工厂方法子类决定单一产品高(新增子类即可)产品多且需灵活扩展(如游戏角色)
抽象工厂统一管理产品族中等(需新增工厂类)产品族关联性强(如跨平台 UI)

实际开发建议

  1. 简单工厂:快速实现原型或产品类型少的场景。
  2. 工厂方法:需要频繁扩展产品类型的场景(如插件系统)。
  3. 抽象工厂:需要保证产品族一致性的场景(如框架设计)。

六、进阶技巧与注意事项

  1. 反射优化简单工厂

    public static Car createCar(Class<? extends Car> clazz) {
        try {
            return clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    

    通过传入类名动态创建对象,减少 if-else 分支

  2. 防止抽象工厂过重

    • 若只需部分产品,可结合工厂方法模式。
  3. 实际案例参考

    • Spring 框架:使用工厂方法(如 BeanFactory)和抽象工厂(如 ApplicationContext)管理 Bean 实例。
    • Java Calendar:通过工厂方法(Calendar.getInstance())根据本地化创建日历对象

七、总结

工厂模式是 Java 开发的基石技能,掌握其核心逻辑和差异能帮助你写出更优雅、可维护的代码。初学者可从简单工厂入手,逐步理解工厂方法和抽象工厂的设计理念。在实际项目中,根据需求选择合适的模式,避免过度设计!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小灰

你的鼓励是我创造最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值