项目结构搭建:从系统结构图到多模块 Maven 项目设计

本文记录了我在餐饮管理系统项目中,从系统结构图设计到多模块 Maven 项目搭建的完整思考过程。


一、从产品原型到系统结构图

在项目初期,我根据产品原型首先尝试绘制系统结构图,用于梳理系统的整体模块划分。

初版结构图的问题

最初绘制的结构图中,各个模块是平级关系,主要关注功能划分,而忽略了:

  • 模块之间的 层级关系
  • 模块之间的 依赖方向
  • 不同模块在工程中的 关注重点

在这一阶段,我逐渐意识到:
系统结构图不只是“模块列表”,而是模块间关系的表达。


结构图的逐步演进

在不断调整后,我对结构图提出了更明确的目标:

  • 能体现 调用层级
  • 能反映 依赖方向
  • 能提示 开发过程中的关键关注点(如高并发、事务敏感、高频读等)

在这一原则下,结构图经历了多次迭代,最终形成了第三版系统结构图,用于指导后续的工程搭建。


二、从系统结构图到项目模块规划

基于最终的系统结构图,我开始尝试将设计落地为实际的项目结构。

初始拆分思路

最初的出发点是:

  • 结构清晰
  • 各层职责独立

因此,我按照经典的三层架构,将项目拆分为三个 Maven Module:

  • controller
  • service
  • dao

从“概念理解”的角度看,这样的拆分似乎是合理的。


三、对照教学案例后的关键反思

在对照教学案例(如 sky-take-out)后,我发现一个非常明显的差异:

教学案例的模块划分方式

案例项目并 没有 将 controller / service / dao 拆分为独立 Maven Module,而是采用了:

  • pojo:实体类与数据模型模块
  • common:通用常量、工具类、公共定义
  • server:业务模块(包含 controller / service / mapper)

并且:所有模块由一个 parent pom 统一管理


我的拆分方式存在的问题

对比之后,我逐渐意识到自己最初的设计存在以下隐患:

  1. controller / service / dao 强耦合、同步演进
  2. 业务变化频繁,模块边界不稳定
  3. 缺少统一的实体与通用模块
    • 实体类、常量、工具类被迫分散在不同模块
    • 不可避免地出现模块间交叉 import
  4. 结构复杂,但并未带来工程收益

最终结果很可能是:模块越拆越乱。


四、什么该拆 Module,什么不该拆

Maven Module ≠ 逻辑分层

在这一阶段,我对 Maven Module 的角色有了更清晰的认识:

Maven Module 的拆分依据不是 MVC 分层,而是工程属性。

更合理的判断标准是:

  • 稳定性:是否长期稳定、不易变化
  • 复用性:是否会被多个模块依赖
  • 变化频率:是否频繁随业务调整

合理的拆分原则

  • 稳定、通用、可复用的内容
    → 适合拆为 Maven Module(如 common、pojo)
  • 强耦合、变化频繁的业务逻辑
    → 更适合作为 package 层次存在(controller / service / mapper)

这一认知也解释了为什么教学案例会选择将 MVC 分层整合在 server 模块中。


五、项目搭建:从“能跑”到“规范”

在统一思路后,我按照案例的工程结构重新搭建了项目,形成了如下多模块 Maven 项目:

1
2
3
4
5
backend-catering-management-system
├── common
├── pojo
├── server
└── pom.xml

父工程的角色

父工程(parent pom)主要职责是:

  • 统一管理依赖版本
  • 统一插件配置
  • 管理子模块(Aggregator)

在这一过程中,我遇到了一个典型的 Maven 报错:

1
Aggregator projects require 'pom' as packaging

问题与结论

通过该问题明确了一个关键规则:

  • 聚合父工程的 packaging 必须是 pom
  • 父工程不参与业务代码编译
  • 只有子模块才是 jar

这一细节也进一步加深了我对 Maven 多模块项目结构的理解。


六、阶段性总结

通过从系统结构图到项目搭建的完整过程,我对后端工程结构有了更清晰的认识:

  • 项目结构不能自由发挥,一切为了方便开发为主
  • 复杂的结构并不一定带来更好的工程效果
  • 知道“为什么不这么拆”,比“我能拆得多细”更重要

学习资料与完整代码

已整理并上传至 GitHub 仓库