当前位置:

首页 > 编程开发 > ThinkPHP大型项目目录结构分层实践_Service层与逻辑层目录

ThinkPHP大型项目目录结构分层实践_Service层与逻辑层目录

Service层封装可复用的领域行为,不处理HTTP状态码与请求参数;Logic层仅用于桥接多个Service,避免写数据库查询;目录结构按业务域垂直切分;Service类应依赖接口,通过构造函数注入以支持单元测试与替换。

Service层只封装可复用、跨Controller的领域行为,比如OrderService::createWithItems()负责库存校验、扣减等,但不处理HTTP状态码、不读Request;参数解析、权限判断等应由中间件或BaseController承担。

ThinkPHP大型项目目录结构分层实践_Service层与逻辑层目录

Service 层该放什么,不该放什么

Service 层不是“写业务逻辑的地方”这个模糊概念的垃圾桶。它只做一件事:封装可复用、跨 Controller 的领域行为。比如 OrderService::createWithItems() 要负责校验库存、扣减、生成流水、发消息——但不处理 HTTP 状态码、不读 Request 对象、不调 view()

常见错误是把参数解析、权限判断、日志埋点塞进来。这些该在中间件或 BaseController 里做。Service 一旦开始 input()->get()session()->get(),就说明职责溢出了。

  • ✅ 正确:调用 GoodsStockService::decrease()、组装 $orderData、事务内写多张表
  • ❌ 错误:从 input() 取参数、手动拼 SQL、返回 json(['code'=>0])
  • ⚠️ 注意:App\Service\Payment\AlipayService 这种第三方对接类可以存在,但它必须被上层 Service 组合调用,不能被 Controller 直接 new

Logic 层和 Service 层怎么划清边界

ThinkPHP 官方没定义 Logic 层,所以项目里出现 App\Logic\ 时,大概率是历史包袱或职责混乱的信号。真要分层,建议只保留 Service,并用子命名空间表达语义层级,比如 App\Service\Order\CreationServiceApp\Service\Order\RefundService —— 它们同属 Order 领域,但动作分离。

如果硬要设 Logic 层,唯一合理场景是:同一业务动作中,需桥接多个 Service 并做轻量协调(无状态、无持久化)。例如 OrderLogic::cancelAndRefund() 内部调 OrderService::cancel() + RefundService::apply(),但它自己不查库、不改库、不加事务。

  • ✅ 合理:Logic 类只 new Service、调方法、return 结果,方法体不超过 10 行
  • ❌ 危险:Logic 类里写 DB 查询、含 if-else 分支逻辑、带事务注解
  • ⚠️ 兼容性提示:TP6 的 think-orm 默认不扫描 Logic 命名空间,若用了依赖注入,得手动在 app/provider.php 里加绑定

目录结构怎么避免“越拆越乱”

大型项目最常犯的错,是按技术类型(如 Controller/Model/Service)平铺三级目录,结果一个订单功能散落在 5 个目录下,改个字段要开 8 个文件。应该按业务域垂直切分,再按职责水平分层。

推荐结构:app/Order/Controller/OrderController.phpapp/Order/Service/OrderService.phpapp/Order/Dto/OrderCreateDto.phpapp/Order/Repository/OrderRepository.php。Domain 层(如 app/Order/Domain/Order.php)可选,但一旦引入,就必须禁止 Service 直接 new Model。

  • ✅ 推荐:app/{Domain}/ 下只放该域相关代码,跨域调用走 Service 接口
  • ❌ 反模式:app/Service/OrderService.php + app/Service/UserService.php + app/Service/OrderUserRelationService.php —— 关系类不该独立成 Service
  • ⚠️ 性能注意:TP6 自动加载基于 PSR-4,app/Order/Service/app/Service/Order/ 更易命中缓存,因为命名空间更短

Service 类如何支持单元测试和替换

Service 不是工具类,它必须能被容器管理、能被 Mock、能被换实现。这意味着不能有静态方法、不能 new 具体类、不能读全局变量。所有外部依赖(DB、缓存、HTTP 客户端)必须通过构造函数注入或接口依赖。

比如 OrderService 依赖库存服务,就该依赖 StockInterface 而非 GoodsStockService。测试时用 Mock 实现,上线时 bind 到真实实现。TP6 的 app/provider.php 是绑定入口,别漏掉。

  • ✅ 正确:public function __construct(private StockInterface $stock)
  • ❌ 错误:new GoodsStockService()Cache::get()Db::table()
  • ? 小技巧:在 app/common.php 里写 function app_service($name) { return app()->get($name); },比直接 new 更利于后期切 AOP

事情说清了就结束。真正难的不是分几层,而是每次新增一个接口时,能不能忍住不把校验、查询、更新、通知全塞进一个方法里。

本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发
相关文章 更多
C++动态数组初始化怎么写?常用语句与代码示例
C++动态数组初始化怎么写?常用语句与代码示例

深入解析C++中动态数组的初始化机制,涵盖new操作符的不同用法、基本类型与类对象的初始化差异,以及为何在现代C++开发中应优先使用std::vector。

BTIG调研:ServiceNow(NOW.US)AI叙事正经历“实质性”积极转变 Q2或成关键起跳点
BTIG调研:ServiceNow(NOW.US)AI叙事正经历“实质性”积极转变 Q2或成关键起跳点

BTIG一线调研显示,ServiceNow的AI叙事正经历实质性积极转变:客户提前续约并接受两位数涨价,分析师给予买入评级与150美元目标价。公司聚焦高端市场,第二季度或成关键起跳点,AI战略驱动增长,市场信心持续增强。

解决apollo的configService服务启动异常
解决apollo的configService服务启动异常

前言 apollo是一个非常流行的开源的配置中心项目,这里就不多介绍了。接触过apollo和运行过apollo的人肯定都遇到过启动configService时抛异常了,而且100%会抛一个异常。原因是,在apollo的架构中configService既作为config服务,同时也承载了metaSer

4.2.1 Service初涉
4.2.1 Service初涉

本节引言 好的,我们在前三节中对Android中的Activity进行了研究学习,相信大家获益良多吧! 本节开始我们继续来学习Android中的第二个组件:Service(服务), 好,废话不多说,开始本节内容! 1.线程的相关概念 在开始学习Service之前我们先来了解下线程的一些概念! 1)相

4.2.2 Service进阶
4.2.2 Service进阶

本节引言 上节我们学习了Service的生命周期,以及两种启动Service的两种方法, 本节继续来深入了解Service中的IntentService,Service的使用实例: 前台服务与轮询的实现! 1.IntentService的使用 在上一节后我们已经知道了如何去定义和启动Service,

android service 常见报错与处理办法汇总
android service 常见报错与处理办法汇总

AndroidService作为后台组件,其开发常遇多种报错。主要涉及生命周期管理不当、进程间通信错误及权限配置问题。例如前台服务未及时调用startForeground()会导致异常,绑定服务时需确保清单文件正确定义和Intent明确。系统后台限制趋严,需适配WorkManager或前台服务。同时须防范内存泄漏,如在Activity销毁前解绑服务,并利用日

java调用webservice 对比指南:不同方案优缺点分析
java调用webservice 对比指南:不同方案优缺点分析

Java调用WebService主要有JAX-WS、ApacheCXF/Axis2、HTTP客户端直接调用及Spring-WS等方案。JAX-WS标准化程度高,适合企业级SOAP服务,但依赖较重。第三方框架如CXF灵活性更强,支持更多功能,但增加了复杂度。直接使用HTTP客户端依赖最简、可控性高,但开发效率低。Spring-WS与Spring生态集成良好,适

ttsservice是什么 使用中遇到的问题怎么解决
ttsservice是什么 使用中遇到的问题怎么解决

TTS服务将文本转为语音,常见问题包括无声或音质异常,应检查音量、引擎及语音数据包;语言或语速不准确,需调整设置与滑块;特定应用无法朗读,应检查权限与兼容性。系统故障可重启、清除数据或恢复出厂设置。用户也可选用第三方引擎优化体验。

pcidevice 实操经验总结:这些技巧很实用
pcidevice 实操经验总结:这些技巧很实用

PCI设备是连接主板与外部硬件的关键接口,其管理与配置对系统优化和虚拟化部署至关重要。Linux下可使用lspci查看设备信息,结合grep过滤定位。高级场景中可通过sysfs文件手动绑定或解绑驱动,实现SR-IOV或设备直通。setpci工具能直接读写配置寄存器,但需谨慎操作。虚拟化直通需启用IOMMU并将设备绑定至vfio-pci驱动。故障排查可。

pcidevice 选型思路:使用场景与区别整理
pcidevice 选型思路:使用场景与区别整理

PCIe设备选型需综合考虑物理接口、版本带宽与使用场景。需明确主板插槽类型、支持的PCIe版本,确保设备兼容。根据图形处理、存储扩展或网络升级等具体需求选择设备类别,并比较关键参数与软硬件兼容性。同时应权衡品牌、预算、散热及未来升级空间,做出适宜选择。

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师
macOS

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

WINDOWS 更多
Windows 10
Windows 10
Windows

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘
Windows/macOS/iOS/Android

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。