中台技术标准

中台技术标准

一、工程结构

统一使用sofaboot的sofa分层方式,SOFA 分层是沿袭自蚂蚁 SOFA 工程的传统分层,蚂蚁传统 SOFA 应用通常基于模块化形式进行开发,解决了模块化开发下各模块相互影响的问题。

工程结构如下:

+appname
|—— app               (应用目录)
|———— common (基础结构层)
|—————— common-util (公共常量,枚举,异常,日志,Log以及工具类等)
|—————— common-dal (ZDAL配置,SqlMap,DO,DAO接口以及实现)
|—————— common-service-facade (对外暴露的API,DTO,Request,Result等)
|—————— common-service-integration (调用外部服务的Wrapper或者Client等)
|———— core (核心/原子服务层)
|—————— core-model (领域模型,支持校验,追踪,环境上下文等)
|—————— core-service (核心/原子服务,领域模型的仓储,缓存,转换器)
|———— biz   (业务逻辑层)

|—————— biz-shared (业务逻辑,入参xxxReq,返回WelfareResult包裹DTO)
|—————— biz-service (对外暴露的API实现类,入参xxxReq,返回DTO)
|———— test   (测试层,单元测试的基类,Test Case和Starter)
|—— conf (SOFA 相关配置存放目录,包括sofa, log4j等配置)
|—— pom.xml (总POM文件)

SOFA 分层对应的模块依赖如下图所示:

test 层(测试层)

该层是 SOFABoot 项目中测试模块,提供了单元测试的基类,支持继承或扩展。由于要对所有模块进行测试,因此该层位于 SOFABoot 系统最顶端,通过直接和间接依赖,可以访问到每个模块的代码,即所有模块对测试层都是可见的。

bootstrap 层(启动层)

该层是 SOFABoot 项目中的启动模块,该模块中会包含 SOFABoot 应用的启动类、同时配置 SOFABoot 打包等。该层通过直接和间接依赖,可以访问到除了测试模块外每个模块的代码。

biz 层(业务应用层)

biz-service-impl

biz-service-impl是facade层的实现,是接口的入口,该层要尽量的薄,不要掺杂太多的业务逻辑,对应的业务逻辑放在shared层进行组装,任何需要在入口做的非业务逻辑都应该放在biz-service-impl用统一的模版进行处理

  • 参数校验
  • 数据库本地事务控制
  • 服务调用,调用shared层对应服务
  • 组装返回结果,将shared返回结果通过WelfareResult进行统一包装(返回结果=VO1,VO2+返回码+描述)
  • 捕获异常
  • 日志出入参打印
  • 数据埋点
  • 其他

biz-shared

biz-shared 层相当于领域驱动设计中的应用层,位于领域层之上,调用的是领域服务,使用的是领域模型,自己则专注于具体应用所需要的逻辑处理,而不包含核心业务规则,更多的是给领域层需要协作的各个领域服务协调任务、委派工作。

  • 该层业务服务类以 Manager 结尾
  • 业务/数据 权限控制在此严格控制,考虑每一次访问是否真的具有对该数据的查看或操作权限
  • 业务写在对应的业务bundle中
  • 实现相对复杂的业务,复用性较低的业务
    例如:复权因子计算、业绩计算、行情排行等对多个数据进行聚合或计算;拼装多个业务逻辑
  • 相对完整、独立的,且有可能被复用的模块业务,或者一些通用的业务工具类,可以抽象到core-service层
    例如:查询人员、审核模块、日期处理类、规则引擎
  • 入参是基本类型或者xxxreqDTO对象、输出结果是没有被WelfareResult包裹的DTO数据

代码示例

/**
 * 文档manager
 *
 * @author yutao create on 2021/12/9 11:27
 */
public interface AlFileManager {

    /**
     * 批量查询接口
     */
    List<FileInfoDTO> fileListByBizId(AlFileQueryByBizIdReqDTO request);

    /**
     * 单个查询接口
     */
    <FileInfoDTO> fileGetById(AlFileGetByIdReqDTO request);

     /**
     * 文档保存
     * @return 文档id
     */
    String fileSave(AlFileSaveReqDTO req);
    
    /**
     * 批量保存
     * @param req
     * @return
     */
    List<String> fileBatchSave(AlFileBatchSaveReqDTO req);
    
    /**
     * 修改文档
     * @param request
     * @return
     */
    Void fileModify(AlFileModifyReqDTO request);
    
}

core 层(核心领域层)

core-model

core-model 模块包含领域层各个模型对象,模型命名以Model结尾,一个实体可以有多个Model

core-service

core-service模块封装核心业务,该层主要有三种类

  • xxxService:领域服务类,要求原子化程度高,通用性强,服务较稳定,改动频率较低,根据是否需要缓存确认继承cacheableBaseService,对数据进行操作时(增、改、删)时应更新缓存,保障缓存一致性。
  • xxxConverter:模型转化类,负责model->DO, DO->model, model->DTO/VO, DTO/VO->model的转化
  • xxxRepository:数据仓库类(可选),复杂数据源场景,数据库操作与服务分离,区分服务与仓库。当一个模型需要通过多个数据源组装,应该将多个数据源的聚合工作放到Repository中,如果只是单纯操作单一数据源(如DB)可以不用添加Repository

common 层(基础结构层)

在 Common 层中包含了为系统提供基础服务的各个模块:

common-service-facade (外观层)

facade 层是应用对外提供的接口层,门面模式在sofa项目中的具体体现。facade 层用于提供接口描述文件(xxxxFacade,DTO),不包含任何业务逻辑(只有接口信息,比如接口定义,接口请求模型和接口返回模型,接口涉及到的enum枚举),该模块使用单独的版本号,需要单独发布打包。

  • 请求类命名格式为:com.alipay.{项目名称}.common.service.facade.{模块名称}.request.xxxxxreq,命名须明确清晰的解释出此接口的作用及用途(格式:操作对象+操作动作+Req)请求都以req结尾,强制要求继承ToString,必须要有serialVersionUID字段,如果请求里面只有一个字段也需要遵守此规范
  • 禁止facade接口含有多个参数(所有的请求都由一个复合对象包裹,理论上来说一个接口一个请求对象)
  • 返回类命名格式为:由统一的WelfareResult包装,对外展示的对象都以DTO结尾,必须继承ToString,必须要有serialVersionUID字段
  • 所有tr接口类都以facade结尾,查询类接口与操作类接口分离,方便后期分zong发布路由,文件查询类与文件操作类的接口分开为FileOperateFacade和FileQueryFacade,考虑到query流量可能较大,后期可能发布czone

common-dal

使用mybaties-generator

sofaboot 推荐的开源组件,使用maven插件生成对应的mapper和DO,使用上比dalgen方便

  • dev库的账号密码要明文写在代码里

common-integration

  • 接口和实现类均使用 client 命名
  • 外部服务依赖均不注册为sofa服务,在实现类中使用 @Autowired 引入服务bean

common-util

  • util 模块则提供了基础的公用的工具服务,工具类命名都以Util结尾。

此处为语雀内容卡片,点击链接查看:https://yuque.antfin.com/middleware/sofaboot

模块间调用规范

理论上各除了本模块的服务,manager层只调用manager层的服务,service层只调用service层的服务

二、命名规范

  • ✅单个对象查询方法命名get*
  • ✅多个对象查询方法命名list*
  • ✅模型命名,视图模型-DTO/VO、领域模型-Model
  • ✅方法命名,*Facade,*FacadeImpl,*Manager,*Service,*Repository
  • ✅接口层透出对象统一以DTO/VO结尾命名
  • ✅接口字段里如果有枚举code或者name,注释上标记 {@link 枚举类}
  • ✅Facade入参,必须包装对象
  • ✅Service根据是否需要缓存确认继承cacheableBaseService
  • ✅facadeImpl必须继承BaseFacadeImpl

三、日志规范

  • ✅各层的请求和返回日志利用AOP通过统一日志拦截器进行打印(包括数据库层)
  • ✅方法独有的业务监控日志通过工具类打印,方便后续自定义业务监控
  • ✅禁止打印堆栈
  • ✅严格根据业务需要,打印error日志,会配置相应监控告警,保障告警有效性。

四、开关配置规范

  • ✅DRM与后台开关默认打开,走正常发布流程

五、其他注意事项

  • ✅尽量使用Integer,不要使用int,int默认为0,不排名和排名为0是两码事
  • ✅根据业务抽出基本对象,减少重复写相同字段
  • ✅在明确的场景下,为集合指定初始容量
  • ✅代码开发时,考虑判空,严防NPE
  • ✅在编码时,也要考虑测试用例的行覆盖率和分支覆盖率,本着从facade入口处调用,从上至下贯穿到dao层,尽量覆盖完全,遇到分支或异常等特殊情况,使用多个case来进行覆盖
  • ✅方法尽量抽象,没有用到或非必须的方法及时删除

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值