
工厂模式是一种创建型设计模式它提供了一种创建对象的最佳方式。在工厂模式中我们在创建对象时不会对客户端暴露创建逻辑并且是通过使用一个共同的接口来指向新创建的对象。说白了就是“解耦”。把“怎么创建对象”和“怎么使用对象”分开。客户端只需要告诉工厂“我要什么”工厂负责把具体的对象造出来交给客户端客户端不需要关心对象是怎么new出来的也不需要关心具体是哪个子类。优缺点分析✅ 优点解耦代码将对象的创建和使用分离客户端不需要知道具体类的类名只需要知道参数或工厂接口降低了耦合度。符合开闭原则当需要增加新的产品类时只需要增加一个新的具体产品类和对应的工厂逻辑或在简单工厂中修改判断逻辑无需修改客户端代码。屏蔽复杂性如果对象的创建过程非常复杂需要依赖注入、读取配置、复杂的计算等工厂模式可以将这些复杂逻辑封装在工厂内部对调用者透明。❌ 缺点类个数增加每增加一个产品通常就需要增加一个具体产品类可能会增加系统的复杂度尤其是抽象工厂模式。抽象难度工厂模式需要抽象出产品的共同接口如果产品设计初期接口定义不合理后期扩展会比较困难。简单工厂违背开闭原则如果是“简单工厂”模式增加新产品时需要修改工厂类的判断逻辑违反了开闭原则。工厂模式的三种实现方式工厂模式主要分为三种简单工厂模式、工厂方法模式、抽象工厂模式。1. 简单工厂模式 (Simple Factory)特点由一个工厂类根据传入的参数动态决定应该创建哪一个产品类。说明严格来说简单工厂模式不属于 GoF 23 种设计模式之一但它是最常用的入门模式。它的缺点是违反“开闭原则”增加新产品需要修改工厂类的if-else或switch逻辑。定义产品接口public interface Product { void use(); }定义具体产品public class ConcreteProductA implements Product { Override public void use() { System.out.println(使用产品 A); } } public class ConcreteProductB implements Product { Override public void use() { System.out.println(使用产品 B); } }定义简单工厂/** * 简单工厂类 * 缺点增加新产品需要修改此处的逻辑违反开闭原则 */ public class SimpleFactory { public static Product createProduct(String type) { if (A.equals(type)) { return new ConcreteProductA(); } else if (B.equals(type)) { return new ConcreteProductB(); } else { throw new IllegalArgumentException(未知产品类型); } } }客户端测试public class Client { public static void main(String[] args) { // 客户端只需要传入类型字符串不需要知道具体类名 Product productA SimpleFactory.createProduct(A); productA.use(); // 输出使用产品 A Product productB SimpleFactory.createProduct(B); productB.use(); // 输出使用产品 B } }2. 工厂方法模式 (Factory Method)特点定义一个创建对象的接口但由实现这个接口的子类来决定实例化哪一个类。说明将实例化的操作延迟到子类中进行。符合“开闭原则”增加新产品时只需增加新的产品类和对应的工厂子类无需修改现有代码。定义工厂接口public interface Factory { Product createProduct(); }定义具体工厂/** * 产品 A 的工厂 */ public class ConcreteFactoryA implements Factory { Override public Product createProduct() { return new ConcreteProductA(); } } /** * 产品 B 的工厂 */ public class ConcreteFactoryB implements Factory { Override public Product createProduct() { return new ConcreteProductB(); } }客户端测试public class Client { public static void main(String[] args) { // 想要产品 A就使用 A 的工厂 Factory factoryA new ConcreteFactoryA(); Product productA factoryA.createProduct(); productA.use(); // 想要产品 B就使用 B 的工厂 Factory factoryB new ConcreteFactoryB(); Product productB factoryB.createProduct(); productB.use(); // 如果要增加产品 C只需新增 ConcreteProductC 和 ConcreteFactoryC无需修改上述代码 } }3. 抽象工厂模式 (Abstract Factory)特点提供一个创建一系列相关或相互依赖对象的接口而无需指定它们具体的类。说明适用于产品族的概念。例如一个工厂能生产“宝马车 宝马发动机”另一个工厂生产“奔驰车 奔驰发动机”。如果只增加一个新产品等级如增加“轮胎”则需要修改所有工厂接口这是其缺点。定义产品族接口// 汽车接口 public interface Car { void drive(); } // 发动机接口 public interface Engine { void start(); }定义具体产品族// 宝马系列 public class BmwCar implements Car { public void drive() { System.out.println(驾驶宝马); } } public class BmwEngine implements Engine { public void start() { System.out.println(启动宝马引擎); } } // 奔驰系列 public class BenzCar implements Car { public void drive() { System.out.println(驾驶奔驰); } } public class BenzEngine implements Engine { public void start() { System.out.println(启动奔驰引擎); } }定义抽象工厂/** * 抽象工厂接口负责生产一族产品 */ public interface AbstractFactory { Car createCar(); Engine createEngine(); }定义具体工厂/** * 宝马工厂只生产宝马系列产品 */ public class BmwFactory implements AbstractFactory { Override public Car createCar() { return new BmwCar(); } Override public Engine createEngine() { return new BmwEngine(); } } /** * 奔驰工厂只生产奔驰系列产品 */ public class BenzFactory implements AbstractFactory { Override public Car createCar() { return new BenzCar(); } Override public Engine createEngine() { return new BenzEngine(); } }客户端测试public class Client { public static void main(String[] args) { // 客户决定要宝马系列整个系列都匹配 AbstractFactory bmwFactory new BmwFactory(); Car myCar bmwFactory.createCar(); Engine myEngine bmwFactory.createEngine(); myCar.drive(); // 驾驶宝马 myEngine.start(); // 启动宝马引擎 // 如果换成奔驰工厂拿到的就是全套奔驰产品保证了产品的一致性 } }三种工厂模式的对比与选择模式核心特点优点缺点适用场景简单工厂一个工厂类通过参数判断创建简单易懂客户端无需关心创建细节违反开闭原则扩展需修改源码产品种类少创建逻辑简单工厂方法一个产品对应一个工厂类符合开闭原则易于扩展新产品类个数成对增加系统复杂度上升产品种类多且经常需要扩展抽象工厂一个工厂生产一族相关产品保证产品族的一致性易于切换产品族增加新产品等级结构困难需改接口需要确保客户端始终使用同一系列的产品工厂模式的潜在问题与防御避免工厂类过于臃肿在简单工厂模式中如果产品类型过多if-else或switch语句会变得极长且难以维护。优化策略改用工厂方法模式。或者在简单工厂中使用Map 反射来注册产品类消除硬编码的判断逻辑。// 优化后的简单工厂示例 (使用 Map 注册) public class OptimizedSimpleFactory { private static final MapString, Class? extends Product registry new HashMap(); static { registry.put(A, ConcreteProductA.class); registry.put(B, ConcreteProductB.class); // 新增产品只需在这里注册无需修改 create 方法逻辑 } public static Product createProduct(String type) { Class? extends Product clazz registry.get(type); if (clazz null) { throw new IllegalArgumentException(未知产品类型); } try { return clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException(创建产品失败, e); } } }结合 Spring 容器在现代 Java 开发特别是 Spring 框架中控制反转 (IoC)容器本质上就是一个超级工厂。我们不再手动编写工厂类。通过Autowired或构造函数注入Spring 容器自动管理对象的生命周期和创建。建议在企业级应用中优先使用 Spring 的 Bean 管理机制除非有非常特殊的动态创建需求否则很少手动实现复杂的工厂模式。