1. 工厂模式概述工厂模式是面向对象编程中最常用的设计模式之一它属于创建型模式主要解决对象创建过程中的灵活性问题。在实际开发中我们经常会遇到需要根据不同条件创建不同对象的场景如果直接在业务代码中使用new关键字实例化对象会导致代码耦合度高、难以维护。工厂模式通过将对象的创建过程封装起来使客户端代码不需要关心具体的实例化细节。工厂模式的核心思想是定义一个创建对象的接口但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。这样做的好处是当需要添加新的产品类时不需要修改现有的客户端代码只需要扩展工厂类即可。工厂模式主要分为三种形式简单工厂模式Simple Factory工厂方法模式Factory Method抽象工厂模式Abstract Factory这三种模式在复杂度和适用场景上有所不同但它们都遵循封装变化的原则将对象创建的过程与使用过程分离。提示工厂模式特别适用于以下场景当创建逻辑比较复杂需要进行各种初始化操作时当需要根据不同的条件创建不同的对象时当系统中需要频繁创建和销毁对象时当希望将对象的创建与使用解耦时2. 简单工厂模式详解2.1 简单工厂模式的结构简单工厂模式是最基础的工厂模式它通过一个工厂类来创建不同类型的对象。其核心组件包括产品接口Product定义产品的公共接口所有具体产品都需要实现这个接口具体产品类ConcreteProduct实现产品接口的具体类工厂类SimpleFactory负责创建具体产品的实例简单工厂模式的UML类图如下所示这里用文字描述Product接口 -|-- ConcreteProductAProduct接口 -|-- ConcreteProductBSimpleFactory -- ConcreteProductASimpleFactory -- ConcreteProductB2.2 简单工厂模式的实现让我们通过一个实际的代码示例来理解简单工厂模式。假设我们正在开发一个支付系统需要支持多种支付方式// 支付接口 - 产品接口 interface Payment { void pay(double amount); } // 支付宝支付 - 具体产品A class Alipay implements Payment { Override public void pay(double amount) { System.out.println(使用支付宝支付 amount 元); // 实际的支付宝支付逻辑... } } // 微信支付 - 具体产品B class WechatPay implements Payment { Override public void pay(double amount) { System.out.println(使用微信支付 amount 元); // 实际的微信支付逻辑... } } // 支付工厂 - 简单工厂 class PaymentFactory { public static Payment createPayment(String type) { if (alipay.equalsIgnoreCase(type)) { return new Alipay(); } else if (wechat.equalsIgnoreCase(type)) { return new WechatPay(); } throw new IllegalArgumentException(不支持的支付类型); } } // 客户端代码 public class Client { public static void main(String[] args) { // 使用支付宝支付 Payment alipay PaymentFactory.createPayment(alipay); alipay.pay(100.0); // 使用微信支付 Payment wechatPay PaymentFactory.createPayment(wechat); wechatPay.pay(200.0); } }2.3 简单工厂模式的优缺点优点客户端不需要知道具体产品类的类名只需要知道对应的参数实现了对象的创建和使用的分离可以通过引入配置文件在不修改客户端代码的情况下更换和增加新的具体产品类缺点工厂类集中了所有产品的创建逻辑职责过重系统扩展困难一旦添加新产品就不得不修改工厂逻辑由于使用了静态工厂方法造成工厂角色无法形成基于继承的等级结构2.4 简单工厂模式的应用场景简单工厂模式适用于以下场景工厂类负责创建的对象比较少客户端只需要传入工厂类的参数不需要关心如何创建对象对象的创建逻辑相对简单不需要复杂的初始化过程在实际项目中简单工厂模式常用于日志记录器可以记录到本地硬盘、系统事件、远程服务器等数据库访问可以连接不同的数据库支付系统支持多种支付方式3. 工厂方法模式详解3.1 工厂方法模式的结构工厂方法模式是对简单工厂模式的进一步抽象化它定义了一个创建对象的接口但由子类决定要实例化的类是哪一个。工厂方法模式让类的实例化推迟到子类中进行。工厂方法模式的主要角色抽象产品Product定义产品的接口具体产品ConcreteProduct实现抽象产品接口的具体类抽象工厂Factory声明工厂方法返回一个产品对象具体工厂ConcreteFactory实现工厂方法返回具体产品实例工厂方法模式的UML类图如下文字描述Product接口 -|-- ConcreteProductAProduct接口 -|-- ConcreteProductBFactory接口 -|-- ConcreteFactoryAFactory接口 -|-- ConcreteFactoryBConcreteFactoryA -- ConcreteProductAConcreteFactoryB -- ConcreteProductB3.2 工厂方法模式的实现继续以支付系统为例我们使用工厂方法模式重构代码// 支付接口 - 抽象产品 interface Payment { void pay(double amount); } // 支付宝支付 - 具体产品A class Alipay implements Payment { Override public void pay(double amount) { System.out.println(使用支付宝支付 amount 元); } } // 微信支付 - 具体产品B class WechatPay implements Payment { Override public void pay(double amount) { System.out.println(使用微信支付 amount 元); } } // 支付工厂接口 - 抽象工厂 interface PaymentFactory { Payment createPayment(); } // 支付宝支付工厂 - 具体工厂A class AlipayFactory implements PaymentFactory { Override public Payment createPayment() { return new Alipay(); } } // 微信支付工厂 - 具体工厂B class WechatPayFactory implements PaymentFactory { Override public Payment createPayment() { return new WechatPay(); } } // 客户端代码 public class Client { public static void main(String[] args) { // 使用支付宝支付 PaymentFactory alipayFactory new AlipayFactory(); Payment alipay alipayFactory.createPayment(); alipay.pay(100.0); // 使用微信支付 PaymentFactory wechatPayFactory new WechatPayFactory(); Payment wechatPay wechatPayFactory.createPayment(); wechatPay.pay(200.0); } }3.3 工厂方法模式的优缺点优点用户只需要知道具体工厂的名称就可得到所要的产品无须知道产品的具体创建过程在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类无须对原工厂进行任何修改满足开闭原则隐藏了产品创建的细节客户端只需要关心产品接口缺点每增加一个产品就需要增加一个具体工厂类增加了系统的复杂度抽象层引入了抽象工厂和抽象产品增加了系统的抽象性和理解难度3.4 工厂方法模式的应用场景工厂方法模式适用于以下场景客户端不知道它所需要的对象的类抽象工厂类通过其子类来指定创建哪个对象需要系统具有良好的扩展性时实际应用包括日志系统不同的日志记录器文件记录、数据库记录等数据库访问不同的数据库连接MySQL、Oracle等框架设计框架定义接口由子类实现具体对象的创建4. 抽象工厂模式详解4.1 抽象工厂模式的结构抽象工厂模式是工厂方法模式的升级版它提供一个创建一系列相关或相互依赖对象的接口而无需指定它们具体的类。抽象工厂模式适用于产品族的场景。抽象工厂模式的主要角色抽象产品AbstractProduct为每种产品声明接口具体产品ConcreteProduct实现抽象产品接口的具体类抽象工厂AbstractFactory声明创建抽象产品对象的操作接口具体工厂ConcreteFactory实现抽象工厂的接口创建具体的产品对象抽象工厂模式的UML类图如下文字描述AbstractProductA -|-- ProductA1AbstractProductA -|-- ProductA2AbstractProductB -|-- ProductB1AbstractProductB -|-- ProductB2AbstractFactory -|-- ConcreteFactory1AbstractFactory -|-- ConcreteFactory2ConcreteFactory1 -- ProductA1ConcreteFactory1 -- ProductB1ConcreteFactory2 -- ProductA2ConcreteFactory2 -- ProductB24.2 抽象工厂模式的实现假设我们正在开发一个跨平台的UI组件库需要支持Windows和Mac两种风格// 按钮接口 - 抽象产品A interface Button { void render(); } // Windows风格按钮 - 具体产品A1 class WindowsButton implements Button { Override public void render() { System.out.println(渲染Windows风格按钮); } } // Mac风格按钮 - 具体产品A2 class MacButton implements Button { Override public void render() { System.out.println(渲染Mac风格按钮); } } // 复选框接口 - 抽象产品B interface Checkbox { void render(); } // Windows风格复选框 - 具体产品B1 class WindowsCheckbox implements Checkbox { Override public void render() { System.out.println(渲染Windows风格复选框); } } // Mac风格复选框 - 具体产品B2 class MacCheckbox implements Checkbox { Override public void render() { System.out.println(渲染Mac风格复选框); } } // GUI工厂接口 - 抽象工厂 interface GUIFactory { Button createButton(); Checkbox createCheckbox(); } // Windows工厂 - 具体工厂1 class WindowsFactory implements GUIFactory { Override public Button createButton() { return new WindowsButton(); } Override public Checkbox createCheckbox() { return new WindowsCheckbox(); } } // Mac工厂 - 具体工厂2 class MacFactory implements GUIFactory { Override public Button createButton() { return new MacButton(); } Override public Checkbox createCheckbox() { return new MacCheckbox(); } } // 客户端代码 public class Client { public static void main(String[] args) { // 创建Windows风格的UI组件 GUIFactory windowsFactory new WindowsFactory(); Button windowsButton windowsFactory.createButton(); Checkbox windowsCheckbox windowsFactory.createCheckbox(); windowsButton.render(); windowsCheckbox.render(); // 创建Mac风格的UI组件 GUIFactory macFactory new MacFactory(); Button macButton macFactory.createButton(); Checkbox macCheckbox macFactory.createCheckbox(); macButton.render(); macCheckbox.render(); } }4.3 抽象工厂模式的优缺点优点隔离了具体类的生成客户端不需要知道什么被创建当一个产品族中的多个对象被设计成一起工作时它能保证客户端始终只使用同一个产品族中的对象增加新的产品族很方便无须修改已有系统符合开闭原则缺点增加新的产品等级结构困难需要修改抽象工厂和所有具体工厂类违背开闭原则增加了系统的抽象性和理解难度4.4 抽象工厂模式的应用场景抽象工厂模式适用于以下场景系统需要独立于产品的创建、组合和表示时系统需要配置多个产品族中的一个来使用时需要强调一系列相关产品对象的设计以便进行联合使用时提供一个产品类库只想显示它们的接口而不是实现时实际应用包括跨平台UI组件库数据库访问层支持多种数据库操作系统文件系统抽象游戏开发中的不同风格场景构建5. 三种工厂模式的比较与选择5.1 三种工厂模式的对比特性简单工厂模式工厂方法模式抽象工厂模式复杂度低中高可扩展性差需要修改工厂类好增加新产品不影响现有代码好增加新产品族不影响现有代码适用场景产品类型少且固定产品类型可能增加产品族需要一起使用抽象程度低中高代码量少中多灵活性低中高5.2 如何选择合适的工厂模式在实际项目中选择工厂模式时可以考虑以下因素产品复杂度如果产品结构简单使用简单工厂模式即可如果产品结构复杂考虑工厂方法或抽象工厂模式扩展需求如果预计产品类型会频繁增加选择工厂方法模式如果预计会有多个产品族需要一起使用选择抽象工厂模式团队技能简单工厂模式最容易理解和实现适合经验较少的团队抽象工厂模式最复杂需要团队成员有较好的设计模式基础项目规模小型项目可以使用简单工厂模式大型项目特别是框架设计更适合使用工厂方法或抽象工厂模式注意不要过度设计。如果项目规模小、需求简单直接使用new创建对象也是可以接受的。设计模式是为了解决复杂性问题而不是为了使用而使用。5.3 工厂模式的最佳实践结合配置文件使用可以将工厂类的配置信息放在配置文件中实现不修改代码即可切换产品类型与单例模式结合工厂类通常不需要多个实例可以设计为单例合理使用依赖注入在现代框架中可以考虑使用依赖注入容器来代替手写的工厂模式考虑性能影响如果对象创建非常频繁且性能敏感可以考虑使用对象池技术保持工厂职责单一一个工厂类最好只负责创建一种类型的产品避免成为上帝工厂6. 工厂模式在实际项目中的应用案例6.1 Spring框架中的工厂模式Spring框架大量使用了工厂模式最典型的是BeanFactory和ApplicationContext。它们都是工厂接口负责创建和管理Bean对象。// Spring中使用工厂模式的示例 ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml); UserService userService (UserService) context.getBean(userService);Spring的工厂模式特点使用配置文件定义Bean及其依赖关系支持多种Bean作用域单例、原型等提供了丰富的生命周期回调方法6.2 JDK中的工厂模式JDK也有许多工厂模式的应用例如Calendar.getInstance()根据本地化设置返回不同的Calendar实现NumberFormat.getInstance()根据本地化设置返回不同的数字格式化对象DriverManager.getConnection()根据URL返回不同的数据库连接6.3 日志框架中的工厂模式主流日志框架如Log4j、SLF4J都使用了工厂模式// SLF4J使用工厂模式创建Logger Logger logger LoggerFactory.getLogger(MyClass.class); logger.info(This is a log message);这种设计使得应用程序可以在不修改代码的情况下切换不同的日志实现。6.4 数据库连接池中的工厂模式数据库连接池如HikariCP、Druid也使用了工厂模式来创建和管理连接// HikariCP使用工厂模式创建数据源 HikariConfig config new HikariConfig(); config.setJdbcUrl(jdbc:mysql://localhost:3306/mydb); config.setUsername(user); config.setPassword(password); HikariDataSource dataSource new HikariDataSource(config); Connection connection dataSource.getConnection();7. 工厂模式的常见问题与解决方案7.1 如何避免工厂类成为上帝类问题描述随着产品类型的增加工厂类可能会变得臃肿包含大量的创建逻辑。解决方案使用工厂方法模式替代简单工厂模式将创建逻辑分散到各个具体工厂中结合策略模式将产品创建逻辑封装为独立的策略类使用依赖注入框架如Spring来管理对象的创建7.2 如何处理产品初始化参数问题描述有些产品在创建时需要复杂的初始化参数。解决方案使用Builder模式来构建初始化参数将参数封装为配置对象使用依赖注入来设置属性示例代码// 使用Builder模式构建复杂产品 Product product new ProductBuilder() .setParam1(value1) .setParam2(value2) .setParam3(value3) .build();7.3 如何实现动态扩展问题描述如何在运行时动态添加新的产品类型而不修改现有代码。解决方案使用反射机制通过类名动态创建产品实例结合配置文件定义产品类与标识符的映射关系使用服务加载机制如Java的ServiceLoader示例代码// 使用反射创建产品实例 String className com.example.MyProduct; Class? clazz Class.forName(className); Product product (Product) clazz.newInstance();7.4 如何处理产品间的依赖关系问题描述当一个产品的创建依赖于其他产品时如何管理这些依赖关系。解决方案使用抽象工厂模式创建相关的产品族引入依赖注入框架在工厂方法中显式处理依赖关系7.5 性能优化建议对象池技术对于创建成本高的对象可以使用对象池来复用实例缓存机制对于不变的产品实例可以在工厂中缓存已创建的对象懒加载延迟对象的创建直到真正需要时原型模式通过克隆现有对象来创建新对象避免重复初始化8. 工厂模式的扩展与变体8.1 静态工厂方法静态工厂方法是一种特殊的简单工厂模式它使用静态方法来创建对象。JDK中有许多这样的例子如Boolean.valueOf()、Collections.emptyList()等。优点方法名可以更有意义不像构造函数必须与类名相同不必在每次调用时都创建一个新对象可以返回原返回类型的任何子类型对象示例public class MyClass { private MyClass() {} // 私有构造函数 // 静态工厂方法 public static MyClass createInstance() { return new MyClass(); } }8.2 多例模式多例模式是工厂模式的一种变体它确保一个类有有限数量的实例并提供对这些实例的全局访问点。实现方式public class Multiton { private static final MapString, Multiton instances new HashMap(); private String key; private Multiton(String key) { this.key key; } public static synchronized Multiton getInstance(String key) { if (!instances.containsKey(key)) { instances.put(key, new Multiton(key)); } return instances.get(key); } }8.3 延迟初始化工厂延迟初始化工厂将对象的创建推迟到第一次使用时这对于创建成本高的对象特别有用。实现示例public class LazyFactory { private volatile Product product; public Product getProduct() { if (product null) { synchronized (this) { if (product null) { product createProduct(); } } } return product; } protected Product createProduct() { // 实际的创建逻辑 return new ConcreteProduct(); } }8.4 参数化工厂参数化工厂允许客户端通过参数指定要创建的对象类型同时保持类型安全。实现示例public interface ProductFactoryT extends Product { T createProduct(); } public class ProductAFactory implements ProductFactoryProductA { Override public ProductA createProduct() { return new ProductA(); } }8.5 依赖注入与工厂模式现代依赖注入框架如Spring、Guice可以看作是工厂模式的升级版。它们提供了更强大的功能自动依赖解析生命周期管理AOP支持配置外部化示例使用SpringService public class MyService { private final MyRepository repository; Autowired public MyService(MyRepository repository) { this.repository repository; } }9. 工厂模式与其他设计模式的关系9.1 工厂模式与单例模式工厂模式经常与单例模式结合使用将工厂类设计为单例工厂类通常不需要多个实例单例工厂可以集中管理产品对象的创建可以更好地控制资源的使用示例public class SingletonFactory { private static final SingletonFactory INSTANCE new SingletonFactory(); private SingletonFactory() {} public static SingletonFactory getInstance() { return INSTANCE; } public Product createProduct() { return new ConcreteProduct(); } }9.2 工厂模式与原型模式工厂模式可以与原型模式结合通过克隆现有对象来创建新对象适用于创建成本高的对象可以避免重复的初始化过程特别适合创建相似但不完全相同的对象示例public class PrototypeFactory { private Product prototype; public PrototypeFactory(Product prototype) { this.prototype prototype; } public Product createProduct() { return prototype.clone(); } }9.3 工厂模式与建造者模式工厂模式和建造者模式都用于创建对象但关注点不同工厂模式关注的是创建什么对象建造者模式关注的是如何创建复杂对象两者可以结合使用工厂决定创建哪种对象建造者负责具体的构建过程9.4 工厂模式与策略模式工厂模式和策略模式经常一起使用工厂模式负责创建策略对象策略模式封装可互换的算法或行为客户端通过工厂获取策略然后使用策略示例public class StrategyFactory { public static SortStrategy createStrategy(String type) { switch (type) { case quick: return new QuickSortStrategy(); case merge: return new MergeSortStrategy(); default: throw new IllegalArgumentException(Unknown strategy); } } }9.5 工厂模式与装饰器模式工厂模式可以与装饰器模式结合动态地为产品添加功能工厂负责创建基础产品装饰器在运行时添加额外功能可以灵活地组合各种功能示例public class DecoratedProductFactory { public Product createBasicProduct() { return new ConcreteProduct(); } public Product createDecoratedProduct() { return new DecoratorA(new DecoratorB(createBasicProduct())); } }10. 工厂模式的测试与调试技巧10.1 如何测试工厂类测试工厂类时应关注以下几点工厂是否能正确创建预期的产品类型创建的产品是否满足接口契约异常情况处理是否合理示例测试代码Test public void testFactoryCreatesCorrectType() { ProductFactory factory new ConcreteProductFactory(); Product product factory.createProduct(); assertTrue(product instanceof ConcreteProduct); } Test public void testProductImplementsInterface() { Product product new ConcreteProductFactory().createProduct(); assertNotNull(product.getDescription()); // 测试接口方法 }10.2 模拟工厂进行单元测试在测试使用工厂的代码时可以使用模拟对象代替真实工厂Test public void testClientWithMockFactory() { // 创建模拟产品 Product mockProduct mock(Product.class); when(mockProduct.doSomething()).thenReturn(test result); // 创建模拟工厂 ProductFactory mockFactory mock(ProductFactory.class); when(mockFactory.createProduct()).thenReturn(mockProduct); // 测试客户端代码 Client client new Client(mockFactory); String result client.execute(); assertEquals(test result, result); }10.3 调试工厂模式的技巧调试工厂模式时可以注意以下方面检查工厂是否正确识别了创建请求验证创建的产品类型是否符合预期跟踪产品的初始化过程检查产品间的依赖关系是否正确建立可以在工厂方法中添加调试日志public Product createProduct(String type) { System.out.println(Creating product of type: type); // 调试日志 // 实际的创建逻辑... }10.4 性能分析与优化对于频繁创建对象的工厂可以进行性能分析使用Profiler工具分析对象创建的开销检查是否有不必要的重复初始化考虑使用缓存或对象池优化性能评估延迟初始化的适用性10.5 常见错误与排查产品类型不匹配检查工厂返回的产品是否实现了正确的接口循环依赖当产品相互依赖时可能导致栈溢出需要重新设计依赖关系内存泄漏长期持有产品引用可能导致内存泄漏确保适当清理线程安全问题多线程环境下共享工厂可能导致问题考虑使用线程局部变量或同步机制11. 工厂模式在现代编程语言中的实现差异11.1 Java中的工厂模式Java中实现工厂模式的特点强类型系统编译时检查产品类型接口和抽象类支持良好可以使用枚举实现简单工厂结合注解和反射实现灵活的产品创建枚举工厂示例public enum ProductFactory { TYPE_A { Override public Product create() { return new ProductA(); } }, TYPE_B { Override public Product create() { return new ProductB(); } }; public abstract Product create(); }11.2 Python中的工厂模式Python实现工厂模式的特点动态类型更加灵活可以使用类方法作为工厂方法支持使用模块作为单例工厂可以利用元类实现自动注册的工厂类方法工厂示例class Product: classmethod def create_product(cls, product_type): if product_type A: return ProductA() elif product_type B: return ProductB() else: raise ValueError(Unknown product type)11.3 JavaScript/TypeScript中的工厂模式JavaScript实现工厂模式的特点可以使用函数或类实现工厂TypeScript增加了接口和类型检查适合创建复杂的配置对象可以与模块系统结合函数工厂示例function createProduct(type) { switch (type) { case A: return new ProductA(); case B: return new ProductB(); default: throw new Error(Unknown product type); } }11.4 C中的工厂模式C实现工厂模式的特点可以使用模板实现通用工厂需要手动管理内存考虑使用智能指针工厂方法可以是虚函数可以结合抽象基类使用智能指针工厂示例class ProductFactory { public: virtual std::unique_ptrProduct createProduct() 0; }; class ConcreteFactory : public ProductFactory { public: std::unique_ptrProduct createProduct() override { return std::make_uniqueConcreteProduct(); } };11.5 Go中的工厂模式Go语言实现工厂模式的特点没有类和继承使用接口和结构体工厂通常是返回接口值的函数简单直接符合Go的哲学可以使用包级别的工厂函数示例type Product interface { Use() } func NewProduct(productType string) (Product, error) { switch productType { case A: return ProductA{}, nil case B: return ProductB{}, nil default: return nil, fmt.Errorf(unknown product type) } }12. 工厂模式在领域驱动设计中的应用12.1 DDD中的工厂概念在领域驱动设计(DDD)中工厂是一种重要的领域模式负责封装复杂对象的创建逻辑确保创建的对象满足不变条件可以重建持久化对象与仓储模式协同工作12.2 聚合根工厂为聚合根创建专门的工厂集中维护聚合的不变条件处理聚合内多个对象的创建和关联可以接收DTO或参数对象作为输入示例public class OrderFactory { public Order createOrder(Customer customer, ListOrderItemDTO items) { Order order new Order(customer); for (OrderItemDTO itemDTO : items) { Product product productRepository.findById(itemDTO.getProductId()); order.addItem(product, itemDTO.getQuantity()); } if (order.getTotal().compareTo(MIN_ORDER_AMOUNT) 0) { throw new BusinessException(Order amount too small); } return order; } }12.3 值对象工厂为值对象创建工厂封装验证逻辑提供有意义的创建方法名可以缓存常用值对象实例示例public class AddressFactory { public static Address create(String street, String city, String zipCode) { validateStreet(street); validateCity(city); validateZipCode(zipCode); return new Address(street, city, zipCode); } private static void validateStreet(String street) { /* ... */ } private static void validateCity(String city) { /* ... */ } private static void validateZipCode(String zipCode) { /* ... */ } }12.4 领域服务作为工厂有时领域服务可以充当工厂当创建逻辑涉及多个聚合协作时需要访问外部资源或服务时创建过程是领域重要行为时示例public class OrderProcessingService { public Order createOrderFromCart(ShoppingCart cart) { Order order new Order(cart.getCustomer()); for (CartItem item : cart.getItems()) { Product product productRepository.findById(item.getProductId()); Inventory inventory inventoryService.checkInventory(product); if (inventory.isAvailable(item.getQuantity())) { order.addItem(product, item.getQuantity()); } } return order; } }12.5 测试DDD中的工厂测试领域工厂时应关注工厂是否强制了领域规则创建的对象是否满足不变条件异常情况是否被正确处理性能是否可接受示例测试Test public void testOrderFactoryEnforcesMinimumAmount() { OrderFactory factory new OrderFactory(); Customer customer new Customer(testexample.com); ListOrderItemDTO items List.of( new OrderItemDTO(prod1, 1) // 总金额小于最小值 ); assertThrows(BusinessException.class, () - { factory.createOrder(customer, items); }); }13. 函数式编程中的工厂模式13.1 高阶函数作为工厂在函数式编程中可以使用高阶函数实现工厂模式工厂是返回函数的函数产品是函数而不是对象可以利用闭包保存状态JavaScript示例function createGreeter(greeting) { return function(name) { return ${greeting}, ${name}!; }; } const sayHello createGreeter(Hello); console.log(sayHello(World)); // Hello, World!13.2 类型类与工厂在Haskell等语言中可以使用类型类实现类似工厂的模式定义类型类作为产品接口为不同类型实现类型类实例使用多态函数作为工厂方法Haskell示例class Product a where use :: a - String data ProductA ProductA instance Product ProductA where use _ Using ProductA data ProductB ProductB instance Product ProductB where use _ Using ProductB createProduct :: String - Maybe (Some Product) createProduct A Just $ Some ProductA createProduct B Just $ Some ProductB createProduct _ Nothing13.3 柯里化与部分应用利用柯里化和部分应用实现灵活的工厂分阶段提供参数创建定制化的产品变体提高代码复用性Scala示例def productFactory(config: Config)(param: Param): Product { // 使用config和param创建产品 } val configuredFactory productFactory(prodConfig) _ val product configuredFactory(param)13.4 纯函数工厂纯函数工厂的特点没有副作用相同输入总是产生相同输出易于测试和推理适合并发环境示例def create_product(config): return { type: config[type], settings: process_settings(config[settings]), # 其他属性... }13.5 函数组合替代继承使用函数组合而不是类继承通过组合简单函数构建复杂行为避免复杂的类层次结构更灵活的运行时组合JavaScript示例const withLogging (product) ({ ...product, log() { console.log(Product: ${this.name}); } }); const createProduct (name) withLogging({ name, use() { /* ... */ } }); const product createProduct(Advanced); product.log();14. 工厂模式与依赖注入容器14.1 传统工厂模式与DI容器的比较特性传统工厂模式DI容器配置方式硬编码或简单配置外部化配置生命周期管理手动管理自动管理依赖解析工厂内部处理容器自动处理灵活性中等高复杂度低到中中到高适用场景简单到中等项目中到大型项目14.2 何时选择传统工厂模式传统工厂模式更适合小型项目或模块创建逻辑简单直接不需要复杂的生命周期管理希望减少外部依赖性能极其敏感的场合14.3 何时选择DI容器DI容器更适合大型复杂项目需要集中管理依赖关系需要高级生命周期管理需要AOP等高级功能团队熟悉DI概念和工具
