ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SpringBoot开发中,我常用的代码结构与分层思路

SpringBoot开发中,我常用的代码结构与分层思路 在经历多个SpringBoot项目的迭代后我逐渐形成了一套相对稳定的代码结构与分层思路。它既不是教条式的DDD领域驱动设计也不同于最简单的Controller-Service-Dao三层架构而是在二者之间找到了一个适合业务快速迭代的平衡点。一、为什么分层不是教条许多团队在项目启动时会花大量时间讨论分层。有人推崇严格的六边形架构有人坚持贫血模型。但我的观点是分层是为了解决“变化”而存在的。如果业务变动频繁分层需要让变动的影响范围可控如果业务相对稳定过度分层反而增加维护成本。基于这个认知我通常采用四层结构接口层、应用层、领域层、基础设施层。但与传统DDD不同的是我不会在每层都建立完整的聚合根和值对象体系而是根据实际业务复杂度灵活调整。二、包结构的实际组织方式我常用的包结构如下text复制下载com.example.order ├── controller // 接口层REST API入口 ├── application // 应用层用例编排 │ ├── service // 应用服务 │ ├── dto // 数据传输对象 │ └── converter // 对象转换 ├── domain // 领域层核心业务逻辑 │ ├── entity // 领域实体 │ ├── repository // 仓储接口 │ └── service // 领域服务 └── infrastructure // 基础设施层 ├── repository // 仓储实现 ├── config // 配置类 └── client // 外部接口调用这里的关键设计是仓储接口放在领域层实现放在基础设施层。这保证了领域层不依赖具体技术实现方便测试和替换。三、各层的职责边界接口层只做三件事参数校验、调用应用服务、组装响应。我见过太多项目在Controller里写业务逻辑这会导致业务逻辑无法复用测试起来也麻烦。应用层是编排者不包含业务规则。比如“创建订单”这个用例应用服务负责调用领域服务创建订单、保存订单、发送通知。但订单金额如何计算、库存如何扣减这些属于领域层。领域层是核心。我通常会把实体设计成充血模型将业务行为内聚在实体中。例如Order实体自身包含calculateTotal()方法而不是在Service中计算。领域服务则处理跨实体的业务逻辑如库存扣减与订单创建的协同。基础设施层负责技术实现包括数据库操作、消息队列、缓存等。这里要注意的是基础设施层不应该包含业务逻辑它只是领域层定义的接口的实现。四、一个具体的例子以订单创建为例代码流转是这样的Controller接收CreateOrderRequest转换为CreateOrderCommand调用OrderApplicationService.createOrder()。应用服务内部调用OrderDomainService.createOrder()领域服务创建Order实体并计算价格然后通过OrderRepository接口保存。基础设施层中的OrderRepositoryImpl负责将实体映射为数据库记录。这种结构下如果数据库从MySQL换成MongoDB只需修改基础设施层的实现领域层和应用层完全不受影响。五、关于DTO的取舍我早期项目会为每一层都定义DTO后来发现这会导致大量无意义的转换代码。现在的做法是接口层使用专门的DTO应用层和领域层之间直接传递实体或Command对象。只有在跨系统调用或需要隔离外部变化时才定义独立的DTO。六、总结这套分层思路的核心在于让业务逻辑远离技术细节。接口层和应用层是薄薄的一层领域层承载核心价值基础设施层负责技术实现。这样当技术栈变化、接口协议调整时核心业务逻辑依然稳固。当然没有放之四海而皆准的架构。如果项目只是简单的CRUD三层结构完全够用如果是复杂的金融系统可能需要更严格的DDD实践。关键在于理解每层存在的意义而不是盲目套用。架构的价值在于让变化发生的时候你依然能从容应对。
返回列表