此文章以项目架构设计层面对代码解耦的尝试。
在以往工作的项目中,碰到了各种项目架构,各自的项目目录整体区别不大,整体以MVC的三层架构为主,只有其中一家公司运用的是四层架构。
三层架构:controller->service->dao
四层架构:controller->biz->service->dao
传统三层架构的缺点:
业务逻辑全放在service层
出现问题:依赖注入的service,mapper特别多, service层业务代码臃肿。业务逻辑复杂的可能会导致大事务的问题。到了后期业务与业务依赖严重,重构很难。就算是微服务架构,也会有这种问题
四层架构相比三层架构优点:
解耦,减少各自领域的相互依赖,也就是耦合性。个人认为这也是代码优化的一种。
个人认为的四层架构的做法:
1、Biz层,注重业务流程的流转,有点类似DDD思想中的Application层。
2、Biz层只能注入Service,各自领域的Service只能注入各自的Mapper, 各自领域Service中严禁注入其它领域的Service和Mapper
3、各自领域的Service只负责处理各自的业务逻辑。
4、Biz层负责对象的转换,比如 BO->VO entity->VO, DTO->BO等等。
可以引用多一层BO对象用于业务逻辑的处理,至于用充血模型或者贫血模型都行
├─biz -- 业务逻辑处理
├─service -- 各自领域业务处理
├─dao -- mapper
├─pojo -- 实体
└─controller -- 控制层
在四层架构中个人觉得已经趋于比较好的解决方案,改造简单,仅仅只多加入一层,对原有的三层架构变动不大,还使得业务更加一步的解耦。
在四层架构中还是觉得有改进的空间,在了解DDD之后根据了解做了以下的目录设计
├─com.freedom.* -- 基础内部服务包
├─application -- 应用层(处理业务流程,不管逻辑)
│ ├─converter -- 转换类(BO->VO, Command->BO)
│ └─service -- 应用层接口
│ ├─cmd -- 应用层增删改接口(必须调用domain->service)
│ └─query -- 应用层查询接口(直调repository层接口)
│
├─domain -- 领域层
│ ├─pojo -- 实体相关类
│ │ └─bo -- 领域层操作对象
│ ├─repository -- 仓储接口
│ └─service -- 领域接口(负责具体的业务逻辑处理,对BO进行操作, 不能注入其它的领域service)
│
├─infrastructure -- 基础设施层
│ ├─config -- 配置文件
│ ├─util -- 工具类
│ ├─constant -- 常量
│ ├─acl -- 防腐层(查询其他服务的数据)
│ ├─enums -- 枚举(主要存放本服务的私有枚举,如外部服务需要则需要放到api包)
│ └─persistence -- 仓储层
│ ├─assembler -- 转换类(向上:PO -> BO, 向下:BO -> PO)
│ ├─mapper -- dao层接口
│ ├─pojo -- 实体相关类
│ │ ├─po -- 对应数据库字段
│ │ ├─query -- 查询对象
│ │ ├─command -- 增,删,改 对象
│ │ └─vo -- 返回前端对象
│ │
│ └─repository -- 仓储接口实现类(负责处理数据, -> DB,ES,Cache)
│
└─interfaces -- 用户界面/展现层
├─controller -- 接口层(-> admin, -> App, -> 其它端)
├─facade -- feign调用接口
├─mq -- 消息中间件处理
└─task -- 定时任务处理
在此设计中:
1、引入了CQRS的概念,读写代码分离。 普通controller层和feign调用的controller分离
2、每一层用不同的实体对象去做不同的事情,职责分离。
更好的架构设计,最终目的是为了代码的解耦。代码结构的耦合,也有可能是设计的问题,导致业务逻辑复杂。
DDD这种项目架构思想,只是个人无聊的尝试。在实际项目中能运用到,运用好四层架构已经是很困难的事情了。
当然如果没有一个严格的代码质量把控,再好的架构也会变得特别乱