本文记录了我在餐饮管理系统项目中,从系统结构图设计到多模块 Maven 项目搭建的完整思考过程。
一、从产品原型到系统结构图
在项目初期,我根据产品原型首先尝试绘制系统结构图,用于梳理系统的整体模块划分。
初版结构图的问题
最初绘制的结构图中,各个模块是平级关系,主要关注功能划分,而忽略了:
- 模块之间的 层级关系
- 模块之间的 依赖方向
- 不同模块在工程中的 关注重点
在这一阶段,我逐渐意识到:
系统结构图不只是“模块列表”,而是模块间关系的表达。
结构图的逐步演进
在不断调整后,我对结构图提出了更明确的目标:
- 能体现 调用层级
- 能反映 依赖方向
- 能提示 开发过程中的关键关注点(如高并发、事务敏感、高频读等)
在这一原则下,结构图经历了多次迭代,最终形成了第三版系统结构图,用于指导后续的工程搭建。
二、从系统结构图到项目模块规划
基于最终的系统结构图,我开始尝试将设计落地为实际的项目结构。
初始拆分思路
最初的出发点是:
- 结构清晰
- 各层职责独立
因此,我按照经典的三层架构,将项目拆分为三个 Maven Module:
- controller
- service
- dao
从“概念理解”的角度看,这样的拆分似乎是合理的。
三、对照教学案例后的关键反思
在对照教学案例(如 sky-take-out)后,我发现一个非常明显的差异:
教学案例的模块划分方式
案例项目并 没有 将 controller / service / dao 拆分为独立 Maven Module,而是采用了:
- pojo:实体类与数据模型模块
- common:通用常量、工具类、公共定义
- server:业务模块(包含 controller / service / mapper)
并且:所有模块由一个 parent pom 统一管理
我的拆分方式存在的问题
对比之后,我逐渐意识到自己最初的设计存在以下隐患:
- controller / service / dao 强耦合、同步演进
- 业务变化频繁,模块边界不稳定
- 缺少统一的实体与通用模块
- 实体类、常量、工具类被迫分散在不同模块
- 不可避免地出现模块间交叉 import
- 结构复杂,但并未带来工程收益
最终结果很可能是:模块越拆越乱。
四、什么该拆 Module,什么不该拆
Maven Module ≠ 逻辑分层
在这一阶段,我对 Maven Module 的角色有了更清晰的认识:
Maven Module 的拆分依据不是 MVC 分层,而是工程属性。
更合理的判断标准是:
- 稳定性:是否长期稳定、不易变化
- 复用性:是否会被多个模块依赖
- 变化频率:是否频繁随业务调整
合理的拆分原则
- 稳定、通用、可复用的内容
→ 适合拆为 Maven Module(如 common、pojo) - 强耦合、变化频繁的业务逻辑
→ 更适合作为 package 层次存在(controller / service / mapper)
这一认知也解释了为什么教学案例会选择将 MVC 分层整合在 server 模块中。
五、项目搭建:从“能跑”到“规范”
在统一思路后,我按照案例的工程结构重新搭建了项目,形成了如下多模块 Maven 项目:
1 | backend-catering-management-system |
父工程的角色
父工程(parent pom)主要职责是:
- 统一管理依赖版本
- 统一插件配置
- 管理子模块(Aggregator)
在这一过程中,我遇到了一个典型的 Maven 报错:
1 | Aggregator projects require 'pom' as packaging |
问题与结论
通过该问题明确了一个关键规则:
- 聚合父工程的 packaging 必须是
pom - 父工程不参与业务代码编译
- 只有子模块才是
jar
这一细节也进一步加深了我对 Maven 多模块项目结构的理解。
六、阶段性总结
通过从系统结构图到项目搭建的完整过程,我对后端工程结构有了更清晰的认识:
- 项目结构不能自由发挥,一切为了方便开发为主
- 复杂的结构并不一定带来更好的工程效果
- 知道“为什么不这么拆”,比“我能拆得多细”更重要
学习资料与完整代码
已整理并上传至 GitHub 仓库
