当前位置: 首页 > news >正文

设计模式--工厂模式

 1、 什么是工厂模式      

        工厂模式的核心目的是将对象的创建与使用分离,它提供了一种创建对象的接口,但让子类决定实例化哪一个类。工厂模式让类的实例化延迟到子类进行。

工厂模式主要分为三种类型,解决不同层次的创建问题:

  1. 简单工厂模式 (Simple Factory Pattern) / 静态工厂方法模式 (Static Factory Method Pattern)

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

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

 2. 简单工厂模式

  • 核心思想: 定义一个工厂类,它根据传入的参数不同,创建并返回不同的具体产品对象。客户端不需要知道具体产品的类名,只需要知道传递给工厂的参数。

  • 结构:

    • 产品接口 (Product Interface): 定义所有具体产品需要实现的公共方法。

    • 具体产品类 (Concrete Products): 实现产品接口的具体类。

    • 工厂类 (Simple Factory): 包含一个静态方法(通常是 createProduct 或类似名字),该方法接收一个参数(如类型标识符),根据这个参数创建并返回对应的具体产品对象。

  • Java 代码示例:

// 1. 产品接口
public interface Phone {void make();
}// 2. 具体产品类
public class IPhone implements Phone {@Overridepublic void make() {System.out.println("Making an iPhone...");}
}public class AndroidPhone implements Phone {@Overridepublic void make() {System.out.println("Making an Android phone...");}
}// 3. 简单工厂
public class SimplePhoneFactory {// 静态工厂方法,根据类型创建产品public static Phone createPhone(String type) {//equalsIgnoreCase:在比较字符串时不区分大小写if ("iphone".equalsIgnoreCase(type)) {return new IPhone();} else if ("android".equalsIgnoreCase(type)) {return new AndroidPhone();} else {throw new IllegalArgumentException("Unknown phone type: " + type);}}
}// 4. 客户端使用
public class Client {public static void main(String[] args) {// 客户端只需要告诉工厂需要什么类型的产品,不需要知道具体类Phone phone1 = SimplePhoneFactory.createPhone("iphone");phone1.make(); // 输出: Making an iPhone...Phone phone2 = SimplePhoneFactory.createPhone("android");phone2.make(); // 输出: Making an Android phone...}
}
  • 优点:

    • 客户端与具体产品类解耦。客户端只需要知道产品接口和工厂类。

    • 将对象的创建逻辑集中在一个地方,便于管理和维护(比如修改创建逻辑、添加日志等)。

  • 缺点:

    • 违反开闭原则 (Open-Closed Principle): 当需要添加新的具体产品时(比如 HuaweiPhone),必须修改工厂类(SimplePhoneFactory)中的 createPhone 方法,添加新的 if-else 分支。

    • 工厂类职责过重,如果产品种类非常多,工厂方法会变得非常臃肿(一个巨大的 switch-case 或 if-else 块)。

    • 静态方法使得工厂类无法基于继承被扩展。

3. 工厂方法模式

  • 核心思想: 定义一个用于创建对象的接口(工厂接口),但让子类决定实例化哪一个具体产品类。工厂方法让类的实例化延迟到其子类。

  • 结构:

    • 产品接口 (Product Interface): 同上。

    • 具体产品类 (Concrete Products): 同上。

    • 工厂接口/抽象工厂类 (Creator): 声明工厂方法 (createProduct()),该方法返回一个产品对象。这个接口/抽象类可能还包含一些依赖于产品对象的业务逻辑。

    • 具体工厂类 (Concrete Creators): 实现或重写工厂接口/抽象工厂类中声明的工厂方法,负责创建特定的具体产品对象。

  • Java 代码示例:

// 1. 产品接口
public interface Phone {void make();
}// 2. 具体产品类
public class IPhone implements Phone {@Overridepublic void make() {System.out.println("Making an iPhone...");}
}public class AndroidPhone implements Phone {@Overridepublic void make() {System.out.println("Making an Android phone...");}
}// 3. 工厂接口 (也可以定义成抽象类)
public interface PhoneFactory {Phone createPhone(); // 工厂方法
}// 4. 具体工厂类 (每个具体产品对应一个具体工厂)
public class IPhoneFactory implements PhoneFactory {@Overridepublic Phone createPhone() {return new IPhone(); // 负责创建iPhone}
}public class AndroidPhoneFactory implements PhoneFactory {@Overridepublic Phone createPhone() {return new AndroidPhone(); // 负责创建AndroidPhone}
}// 5. 客户端使用
public class Client {public static void main(String[] args) {// 客户端选择使用哪个具体工厂PhoneFactory iphoneFactory = new IPhoneFactory();Phone phone1 = iphoneFactory.createPhone(); // 通过工厂方法创建产品phone1.make(); // 输出: Making an iPhone...PhoneFactory androidFactory = new AndroidPhoneFactory();Phone phone2 = androidFactory.createPhone();phone2.make(); // 输出: Making an Android phone...}
}
  • 优点:

    • 完全符合开闭原则: 当需要添加新的具体产品(如 HuaweiPhone)时,只需要添加一个新的具体工厂类(HuaweiPhoneFactory)实现工厂接口即可。不需要修改现有的工厂接口和客户端代码(假设客户端通过配置或依赖注入等方式获得工厂)。

    • 客户端代码只依赖于产品接口和工厂接口,与具体产品类和具体工厂类解耦。

    • 单一职责原则:每个具体工厂只负责创建一种产品,职责清晰。

  • 缺点:

    • 类的数量增多。每增加一个产品,就需要增加一个具体产品类和一个具体工厂类,系统复杂度增加。

    • 增加了系统的抽象性和理解难度。

4.抽象工厂模式

  • 核心思想: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它围绕一个超级工厂创建其他工厂。抽象工厂模式是工厂方法模式的扩展,用于创建产品族(多个相关的产品)。

  • 结构:

    • 抽象产品接口 (Abstract Product Interfaces): 定义一类产品的接口。通常有多个抽象产品接口(如 PhoneTabletWatch)。

    • 具体产品类 (Concrete Products): 实现特定的抽象产品接口,属于同一个产品族(如 IPhoneIPadAppleWatch 都属于 Apple 产品族;GalaxyPhoneGalaxyTabGalaxyWatch 都属于 Samsung 产品族)。

    • 抽象工厂接口/类 (Abstract Factory): 声明一组用于创建不同抽象产品的方法(如 createPhone()createTablet()createWatch())。每个方法返回一个抽象产品。

    • 具体工厂类 (Concrete Factories): 实现抽象工厂接口/类。每个具体工厂负责创建属于特定产品族的所有具体产品(如 AppleFactory 创建PhoneIPadAppleWatchSamsungFactory创建 GalaxyPhoneGalaxyTabGalaxyWatch)。

  • Java 代码示例:

// 1. 产品接口
public interface Phone {void make();
}// 2. 具体产品类
public class IPhone implements Phone {@Overridepublic void make() {System.out.println("Making an iPhone...");}
}public class AndroidPhone implements Phone {@Overridepublic void make() {System.out.println("Making an Android phone...");}
}// 3. 工厂接口 (也可以定义成抽象类)
public interface PhoneFactory {Phone createPhone(); // 工厂方法
}// 4. 具体工厂类 (每个具体产品对应一个具体工厂)
public class IPhoneFactory implements PhoneFactory {@Overridepublic Phone createPhone() {return new IPhone(); // 负责创建iPhone}
}public class AndroidPhoneFactory implements PhoneFactory {@Overridepublic Phone createPhone() {return new AndroidPhone(); // 负责创建AndroidPhone}
}// 5. 客户端使用
public class Client {public static void main(String[] args) {// 客户端选择使用哪个具体工厂PhoneFactory iphoneFactory = new IPhoneFactory();Phone phone1 = iphoneFactory.createPhone(); // 通过工厂方法创建产品phone1.make(); // 输出: Making an iPhone...PhoneFactory androidFactory = new AndroidPhoneFactory();Phone phone2 = androidFactory.createPhone();phone2.make(); // 输出: Making an Android phone...}
}
  • 优点:

    • 保证产品兼容性: 确保客户端创建的所有产品都来自同一个产品族(如都是 Apple 风格或都是 Samsung 风格),避免不兼容产品的组合。

    • 符合开闭原则 (针对产品族): 添加一个新的产品族(如 Huawei 产品族)非常容易,只需要添加一个新的具体工厂(HuaweiFactory)和该族下的所有具体产品类(HuaweiPhoneHuaweiTablet),不需要修改抽象工厂和已有的具体工厂

    • 单一职责/开闭原则 (针对产品等级): 将创建不同产品族的逻辑隔离在不同的具体工厂中。

  • 缺点:

    • 难以支持新种类的产品: 如果需要在抽象工厂接口中添加一个新的产品类型(如 createWatch()),那么所有的具体工厂(AppleFactorySamsungFactoryHuaweiFactory)都需要被修改来实现这个新方法,这违反了开闭原则(针对产品等级结构)。

    • 类的数量剧增: 产品等级(产品种类,如 Phone, Tablet)和产品族(品牌,如 Apple, Samsung)越多,需要的具体工厂和具体产品类就越多,系统变得非常庞大和复杂。

    • 增加了系统的抽象性和理解难度。

5.总结与对比

特性简单工厂模式工厂方法模式抽象工厂模式
目的封装对象创建,隐藏细节让子类决定实例化哪个类创建相关或依赖的产品族
关键参与者工厂类(含静态方法)工厂接口 + 具体工厂类抽象工厂接口 + 具体工厂类
创建对象单一类型的不同产品单一类型的不同产品多个相关类型 (产品族) 的不同产品
开闭原则违反 (添加新产品需改工厂)支持 (添加新产品只需加新工厂)支持产品族扩展 (添加新族容易)
不支持产品等级扩展 (添加新种类难)
复杂度
类数量较多 (每产品一工厂)非常多 (每族 * 每产品等级)
适用场景产品种类少且稳定,不常扩展产品种类可能扩展,客户端只需一种需要创建多个相关对象
且这些对象需要属于同一族或兼容

6.如何选择?

  • 简单工厂: 适用于对象创建逻辑简单,产品种类相对固定且不会频繁增加的情况。快速有效,但扩展性差。

  • 工厂方法: 适用于只涉及创建单一类型产品,但未来可能需要扩展该类型下具体产品的情况。是解耦和扩展性的良好平衡。

  • 抽象工厂: 适用于需要创建多个相互关联或依赖的对象(一个产品族),并且需要保证这些对象兼容的场景(如 GUI 库创建不同操作系统的窗口、按钮、文本框)。当产品族相对稳定,但具体产品可能变化或扩展时最合适。

        理解工厂模式的这三种形态及其适用场景,对于设计灵活、可维护、可扩展的 Java 应用程序至关重要。它们都服务于“解耦创建者与具体类型”这一核心目标,只是在不同复杂度层面提供了解决方案。

http://www.dtcms.com/a/278922.html

相关文章:

  • SSE(Server-Sent Events)和 MQTT(Message Queuing Telemetry Transport)
  • 多线程--单例模式and工厂模式
  • 研究人员利用提示注入漏洞绕过Meta的Llama防火墙防护
  • 隐藏源IP的核心方案与高防实践
  • 缺乏项目进度验收标准,如何建立明确标准
  • 基于STM32的智能抽水灌溉系统设计(蓝牙版)
  • 几种上传ipa到app store的工具
  • C#/.NET/.NET Core技术前沿周刊 | 第 46 期(2025年7.7-7.13)
  • 当前(2024-07-14)视频插帧(VFI)方向的 SOTA 基本被三篇顶会工作占据,按“精度-速度-感知质量”三条线总结如下,供你快速定位最新范式
  • 文本生成视频的主要开源模型
  • Redis客户端编程
  • python之Scikit-learn章节
  • 【日常技能】excel的vlookup 匹配#N/A
  • 《大数据技术原理与应用》实验报告二 熟悉常用的HDFS操作
  • 【王树森推荐系统】聚类召回
  • git 访问 github
  • 多用户图书管理系统
  • 张艺兴探班RED女团一周年舞台,见证21岁的梦想落地生根
  • sqli-labs靶场通关笔记:第11-16关 POST请求注入
  • 文献查找任务及其方法
  • 车载诊断框架 --- 车载诊断GuideLine
  • 【t检验】用奶茶店排队案例解释
  • urlencode、html实体编码、unicode
  • ChatDev 简易指导文档
  • Spring Boot Cucumber 测试报告嵌入方法
  • gitlab-ci.yml
  • ps如何批处理文件(批量裁剪,批量设置文件大小)
  • RNN(循环神经网络)
  • 青岛国瑞 RCV 带来的独特价值
  • MinIo快速入门