开发框架搭建考量

Version:0.9 Starthtml:0000000105 EndHTML:0000064633 StartFragment:0000000141 EndFragment:0000064597
 
本文梳理了在搭建开发框架时的一些考量及具体的处理方法 。
 
框架搭建目标

  • 整体代码规范化
  • 重复代码自动化
  • 复杂关系精简化
  • 公共代码统一化
尽量保证开发人员的核心关注点在业务逻辑 。
尽量避免非业务问题影响开发进度 。
整体代码规范化规范的作用不是为了规范而规范,也不是对不按规范的人做出惩罚 。是为了方便沟通 。
  • 方便新员工能根据规范文档快速熟悉代码结构
  • 方便接手其他人的代码时,只需要了解业务就可以
  • 方便和其他人沟通时,不需要关注业务之外的内容
可以从下面几个方面做出规范:
  • 统一格式化
    • 一种方案是使用相同的IDE,一种方案是使用相同的格式化配置
    • 保证在代码合并或代码review时,不会因为代码格式化问题导致冲突或难以对比
  • 统一三方库的使用
    • 统一使用一种功能的库,比如:持久化框架选定了Mybatis就不要再用Hibernate,安全框架选定了SpringSecurity就不要使用Shiro
    • 这会增加团队成员的学习成本,以及后续的维护成本
  • 统一代码风格
    • 命名方式的统一:命名实际上是个很重要但是一直不被重视的工作 。好的命名能极大的降低沟通成本 。至少要保证包层级的名称的语义 。我接触的项目里,对DTO来说,有的项目里叫PO,有的叫VO,导致一个开发人员接收另一个项目时,理解上就有了难度 。
    • 职责区分:SRP是一个看起来简单,但是很难做好的设计原则 。比如:还是拿DTO来说,有的项目直接会直接将Entity作为DTO来使用,可以避免DTO与Entity直接的数据字段处理 。实际上这里的DTO即做了DTO的工作,又做了Entity的工作 。逻辑简单时是比较爽,但是因为两个对象的职责不一样,进化频率也不一样 。当DTO字段调整时,就会对后面的DAO操作产生影响 。
    • RESTful规范化:现在大部分的项目都会使用RESTful 。如果使用了RESTful,那就按照RESTful的规范来 。尽量提高代码语义,不要使用个四不像 。比如:就使用POST和GET 。
    • 非业务字段独立:业务相关对象和非业务相关对象区分开 。例如:对于查询来说,可能需要进行分页 。对于分页控制字段建议整合为PageInfo对象来统一处理,而不要作为独立的字段加到DTO对象里 。一是不方便管理,二是将不同场景的字段混合到了一起,不易于区分 。
    • 接口携带版本号:接口携带版本号,可以基于版本来进行平滑升级 。例如:可以保留/api/user/v1/login,同时发布/api/user/v2/login,待/api/user/v1/login不再使用后,在删除/api/user/v1/login
  • 代码架构匹配
    • 架构设计时,实际触及到的是系统、子系统、层级、模块;而具体到代码,只体现了系统(一个个的服务)和层级(Controller,Service,DAL) 。模块的映射关系消失了 。
    • 为了提高代码与架构的匹配度,降低沟通成本 。可以在代码层面通过添加一层包的方式,来映射模块关系 。
  • 接口与实现的层级关系(推荐)
    • 传统MVC框架是按照Controller、Service和DAO的方式来分层的 。如果有接口,一般情况下接口定义与实现是在同一层的,比如Service和ServiceImpl,都在Service层 。实际上此种结构是有问题的 。
    • 假设现在有两套Service的实现,代码在项目中如何存储?
    • 实际上Service和ServiceImpl分属不同的层,Service是接口层,ServiceImpl是实现层(虽然可能感觉不符合常识,不过确实如此) 。两套ServiceImpl对应到Maven项目中,就是两个模块 。当要替换实现时,通过Maven的项目结构调整依赖即可 。
重复代码自动化在代码规范化的前提下,基于代码生成工具(比如IDEA的EasyCode)构建一套完整的代码模板,基于代码模板快速的生成对应的代码 。提高开发效率 。
对于库表结构调整后对代码的影响,可以基于代码结构的调整来尽量减少对现有代码的影响 。假设使用Mybatis作为持久化框架,有三个方案:
  • 基于MybatisPlus(其实就是接口继承,具体参考MybatisPlus文档)
  • 基于MybatisProvider
  • 基于MApper接口继承
基于MybatisProvider