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

工厂方法模式

在这里插入图片描述

归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言​📝
把命运掌握在自己手中!
一起加油!

在这里插入图片描述

工厂方法模式

在面向对象编程中,工厂方法模式(Factory Method Pattern) 是一种经典的创建型设计模式。它通过定义一个用于创建对象的接口,但让子类决定实例化哪一个类,从而将对象的创建延迟到子类中。本篇博客将结合一个具体的案例——电视机工厂系统,深入讲解工厂方法模式的结构、实现要点、优缺点,并完整展示如何在 Java 中实现该模式。


一、任务背景

假设我们有一个电视机生产系统,最初只有一个工厂负责生产所有品牌的电视机。但随着业务扩展,我们需要支持海尔、海信、TCL、创维等多个品牌,并希望在新增品牌时无需修改原有代码,以提高系统的灵活性和可扩展性

这时,工厂方法模式就派上了用场。
在这里插入图片描述


二、工厂方法模式的角色

工厂方法模式包含以下四个核心角色:

角色说明
Product(抽象产品)定义产品的接口,所有具体产品都必须实现该接口。例如 TV 接口。
ConcreteProduct(具体产品)实现抽象产品接口的具体类。如 HaierTVHisenseTV
Factory(抽象工厂)声明工厂方法,该方法返回一个 Product 类型的对象。如 TVFactory 接口。
ConcreteFactory(具体工厂)实现工厂方法,负责创建具体产品对象。如 HaierTVFactoryHisenseTVFactory

三、实现要点

  1. 统一产品接口
    所有产品(电视机)必须实现同一个接口(TV),确保客户端代码可以以统一方式使用不同品牌的产品。
  2. 抽象工厂接口
    定义一个工厂接口(TVFactory),声明创建产品的方法(produceTV())。
  3. 具体工厂实现
    每个品牌对应一个具体工厂类,重写工厂方法,返回对应品牌的产品实例。
  4. 配置驱动创建
    通过配置文件(如 XML)动态指定要使用的工厂类,实现运行时解耦。

四、代码实现

1. 抽象产品接口:TV.java

package step3;public interface TV {void play();
}

2. 具体产品类

// HaierTV.java
package step3;public class HaierTV implements TV {@Overridepublic void play() {System.out.println("海尔电视机播放中......");}
}// HisenseTV.java
package step3;public class HisenseTV implements TV {@Overridepublic void play() {System.out.println("海信电视机播放中......");}
}

3. 抽象工厂接口:TVFactory.java

package step3;public interface TVFactory {TV produceTV();
}

4. 具体工厂类(填空部分)

// HaierTVFactory.java
package step3;public class HaierTVFactory implements TVFactory {@Overridepublic TV produceTV() {return new HaierTV(); // ← 填空处}
}// HisenseTVFactory.java
package step3;public class HisenseTVFactory implements TVFactory {@Overridepublic TV produceTV() {return new HisenseTV(); // ← 填空处}
}

5. 配置文件读取工具:XMLUtil.java

package step3;import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;public class XMLUtil {public static Object getBean() {try {DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = dFactory.newDocumentBuilder();Document doc = builder.parse(new File("./src/FactoryMethodconfig.xml"));NodeList nl = doc.getElementsByTagName("className");Node classNode = nl.item(0).getFirstChild();String cName = classNode.getNodeValue();Class<?> c = Class.forName(cName);return c.newInstance();} catch (Exception e) {e.printStackTrace();return null;}}
}

6. 客户端代码:Client.java

package step3;public class Client {public static void main(String args[]) {try {TV tv;TVFactory factory;factory = (TVFactory) XMLUtil.getBean(); // 从配置文件读取工厂类tv = factory.produceTV();tv.play();} catch (Exception e) {System.out.println(e.getMessage());}}
}

7. 配置文件示例:FactoryMethodconfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<config><className>step3.HaierTVFactory</className>
</config>

若想切换为海信电视,只需将 <className> 改为 step3.HisenseTVFactory无需修改任何 Java 代码


五、工厂方法模式的缺点

尽管工厂方法模式带来了良好的扩展性,但也存在一些不足:

  • 类数量成对增加:每新增一个产品,就需要新增一个对应的工厂类,系统复杂度上升。
  • 抽象层次加深:对初学者而言,理解多个抽象层和间接调用可能有一定难度。
  • 配置管理成本:依赖外部配置(如 XML)虽然灵活,但也增加了部署和维护的复杂性。

六、总结

通过本案例可以看出,工厂方法模式完美解决了“在不修改现有代码的前提下扩展新产品”的问题,符合开闭原则(对扩展开放,对修改关闭)

当你需要:

  • 支持多种产品变体;
  • 将对象创建逻辑与使用逻辑分离;
  • 通过配置动态切换实现类;

那么,工厂方法模式是一个非常合适的选择。

💡 扩展思考:如果产品种类非常多(如上百种电视品牌),可以考虑结合反射 + 注解或使用Spring 的 BeanFactory来进一步简化工厂类的编写。


设计模式不是银弹,而是工具。合理使用,方能事半功倍。

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

相关文章:

  • 做装机u盘那个网站好市桥做网站
  • SAP MM采购对账功能分享
  • 网页设计与网站建设考试名词解释2019网站建设工作的作用
  • 【有源码】基于Python与Spark的火锅店数据可视化分析系统-基于机器学习的火锅店综合竞争力评估与可视化分析-基于用户画像聚类的火锅店市场细分与可视化研究
  • Linux: perf: sched latency,周期性抓取看趋势,做对比
  • 统计学重要思想
  • Android 本地存储方案深度解析:SharedPreferences、DataStore、MMKV 全面对比
  • 网站开发前后端中山做外贸网站
  • ElastiCache Redis 内存告警深度分析与运维实战指南
  • Spring5.3.10源码编译和调试(IDEA+Gradle)的过程
  • JS | 知识点总结 - 原型链
  • 【Docker】Docker镜像仓库
  • EEException: Geometry.area: Unable to perform this geometry operation.
  • 逻辑和共情
  • linux安装输入法
  • git连接远程仓库并拉去推送以及克隆命令
  • steam新品节游戏推荐!手机怎么玩steam游戏!
  • OpenHarmony Stage模型深度解剖:从Ability Kit到沙箱隔离的全链路底层原理
  • 基于 GEE 的 MODIS 昼夜地表温度数据可视化与导出全流程解决方案
  • 【Docker】记录一次使用docker部署dify网段冲突的问题
  • 缓存三剑客问题
  • 构建AI智能体:六十七、超参数如何影响大模型?通俗讲解原理、作用与实战示例
  • timm教程翻译:(一)Overview
  • 手写Spring第5弹:告别项目混乱:用Maven构建标准Java项目目录结构
  • Vue3 表单输入绑定
  • 手机app制作网站网站后台尺寸一般做多大的
  • C程序中的选择语句
  • OpenCV进阶:图像变换、增强与特征检测实战
  • 自己做的网站怎样对接支付宝php餐饮美食店网站源码 生成html
  • 【大数据技术实战】Kafka 认证机制全解析