0

0

如何利用Java多态实现简单工厂模式_解耦对象创建逻辑

P粉602998670

P粉602998670

发布时间:2026-03-09 11:47:02

|

383人浏览过

|

来源于php中文网

原创

简单工厂将对象创建逻辑集中到工厂类中,使业务代码只依赖接口而不关心具体实现,从而实现解耦;新增支付方式只需修改工厂类,无需改动业务代码。

如何利用java多态实现简单工厂模式_解耦对象创建逻辑

为什么简单工厂里不能直接 new 具体类

因为一旦在业务代码里写 new PaymentWechat()new PaymentAlipay(),创建逻辑就和使用逻辑绑死了。后续加新支付方式、换实现、做 mock 测试,都得改业务代码——这不是解耦,是焊死。

简单工厂的核心动作,就是把 new 这个操作收拢到一个单独的类(比如 PaymentFactory)里,用多态向上转型,让调用方只依赖 Payment 接口,不关心背后是谁。

  • 工厂方法返回类型必须是接口或父类,比如 Payment create(String type)
  • 所有具体实现类(PaymentWechatPaymentAlipay)都要实现该接口
  • 工厂内部用 if-elseswitch 判断类型,但外部完全看不到这些分支

如何让工厂支持新增类型而不改原有代码

严格来说,标准简单工厂做不到“完全不改”——它的 create() 方法里必然有判断逻辑。但可以控制修改范围:只动工厂类,不动业务类、不改接口、不碰已有实现类。

常见错误是把类型字符串硬编码在业务侧:factory.create("wechat"),结果哪天拼错成 "weichat",运行时报 NullPointerException 都不知道哪来的。更稳妥的是用枚举限定合法类型。

立即学习Java免费学习笔记(深入)”;

科大讯飞-AI虚拟主播
科大讯飞-AI虚拟主播

科大讯飞推出的移动互联网智能交互平台,为开发者免费提供:涵盖语音能力增强型SDK,一站式人机智能语音交互解决方案,专业全面的移动应用分析;

下载
  • 定义 enum PaymentType { WECHAT, ALIPAY, UNIONPAY }
  • 工厂方法签名改为 Payment create(PaymentType type),避免字符串误传
  • 新增类型时,只需扩展枚举 + 在工厂 switch 中加一个 case + 写新实现类
  • 不要在工厂里用 Class.forName().newInstance()——反射绕过编译检查,出错晚、难调试

多态在这里到底起了什么作用

不是为了炫技,而是让“调用方不感知实现变化”。业务代码拿到的是 Payment 类型的引用,调用 pay() 时,JVM 根据实际对象类型自动分派到对应实现——这个动态绑定过程,就是多态在扛事。

如果工厂返回的是具体类型(比如 PaymentWechat),那业务代码变量声明也得跟着变,一加新支付方式就得批量改声明、改调用,彻底失去弹性。

  • 接口定义行为契约:void pay(BigDecimal amount)
  • 每个实现类覆盖自己的逻辑,但签名不变
  • 工厂返回 Payment,业务代码只调 payment.pay(...),连 instanceof 都不该出现
  • 测试时可直接传入 mock 实现,无需启动真实支付通道

简单工厂和策略模式容易混淆的边界

它们长得像,但目的不同:简单工厂专注“怎么造出来”,策略模式专注“造出来后怎么用”。你可能在一个项目里同时用两者——工厂负责生成策略实例,策略接口本身由多态驱动。

典型踩坑是把工厂类写成策略上下文:比如在 PaymentContext 里既缓存实例又做类型路由。这会让职责混乱,一旦要支持同一类型多个配置(如两个不同的微信商户号),就卡住。

  • 工厂只做一件事:根据输入,返回一个符合接口的新对象
  • 策略上下文(如 PaymentExecutor)负责持有、执行、切换策略,不参与创建
  • 如果创建逻辑变复杂(比如需依赖配置中心、需初始化连接池),简单工厂应升级为工厂方法或抽象工厂,而不是硬塞更多 if

多态是基础,但别指望靠它掩盖设计失衡。工厂类开始出现“创建前校验参数”“创建后设置回调”“缓存单例实例”这些逻辑时,就该停下来想想:它是不是已经不只是“简单”工厂了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

990

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

569

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

441

2024.03.13

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

739

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

220

2023.09.04

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

59

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11万人学习

Java 教程
Java 教程

共578课时 | 79.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号