项目代码架构-业务分层和各层业务逻辑

项目代码架构分层

1、代码分层现状

传统项目开发中,代码分层架构大概是controller层,Service层,Dao层,在SOA架构中会有facade层,Service层,Dao层,两种方式都是将所有的业务逻辑集中在Service层,包括业务参数的校验逻辑,业务的核心逻辑,对第三方工具的访问逻辑,甚至是持久层的转换逻辑都在这一层,对持久层数据库的访问则写在Dao层;可以发现所有业务都耦合在service层,使所有业务高度耦和,不仅增加了业务理解的难度,同时对后期的开发维护以及升级都代码了极大的困难;

2、代码分层思考

很长一段时间,开发中项目应该是什么样的分层才能够更合理,有没有一中代码架构分层,可以将每个项目中通用的逻辑与具体的业务逻辑分开,可以清晰的知道每一层核心业务是什么,这样对不仅有利于项目的开发,更加有利于后期项目的维护和扩展,从而延长项目的生命周期;
基于以上思考,我们首先分析了代码项目中拥有哪些可以提取的通用的业务逻辑,从而为项目分层组到有章可循:

  1. 参数校验逻辑:所有项目中都有参数校验的逻辑,参数校验又可以分为基本校验,业务校验
    a、基本校验:参数非null,日期大于当下,年龄字段必须大于零等基本的和业务无关的基本校验;
    b、业务校验:传进来的参数所对应的业务数据是否合法,比如用户id对应的用户数据是否存在且合法业务校验;
  2. 参数转换逻辑:不同模块之间参数转换隔离,做到模块升级不影响其他模块的业务。
    这里的转换是就是将其模块或其他三方工具中的数据对象转成我们业务中的数据对象,以达到隔离和防腐的目的;
    例如:我们使用MySql数据库来持久化数据,后来由于业务发展需要,改成了mongdb,二者返回的数据对象是不一样的,这时候我们只需要在防腐层实现新数据对象映射到我们需要的数据对象就可了。
  3. 异常处理:分为异常的抛出和异常的捕获处理与转换
    a、异常抛出:我们认为,不符合业务的异常均应手动抛出,比如参数校验的异常,不符合业务逻辑的异常等;对于第三方工具类抛出的异常我们任务可以统一包装成三方异常,对外抛出;
    b、异常捕获:异常的捕获应该统一处理,我们任务在出口层应该对所有异常做统一的拦截,避免到处try、catch异常逻辑与正常的业务逻辑耦和在一起;
    c、异常处理:将捕获所有的异常,并将异常的堆栈信息记录下来,对于业务异常可以设置统一的异常码外加异常信息返回给用户,同时对于未知的异常统一转换成定义的系统异常对外抛出;
3、代码分层探索

基于以上思考,我们对代码架构分层做了以下的探究实践;

  1. facade层:门面层:只有接口和接口入参,以及入参中的一些枚举和异常
    a、这一层主没有任何的业务和逻辑,因为这一层是作为二方包提供给其他使用者调用的,所以这一层要保证绝对的干净。
    b、这一层如果需要有业务逻辑的话,我们认为可以将接口签名算法的业务逻辑放在这一层,方便调用方使用现成的签名算法快速方便的调用接口;
  2. interface层:参数转换校验以及异常的捕获处理转换
    a、接口层完成参数转换,转换成下层业务需要的稳定的数据对象,这样能够保证业务数据变动不对使用方造成影响;对于基本数据类型的转换,我们认为放在数据对象的set方法中比较合理,因为这样可以避免每次转换都写校验逻辑,可以减少大量重复代码的开发;对于业务参数的校验,我们也提倡放interface的service层实现,这样可以做到fastfail,避免后面业务中在检查业务参数而造成的一些性能的浪费;
    b、异常的拦截处理,所有的异常应该在这一层拦截和捕获和记录,然后对不同的异常分类处理,对于预期异常我们可以按既定策略返回;对于其他异常,则应该统一转成其他(或系统)异常对外抛出,注意避免将异常信息直接展示给用户。
    c、infrastructure层:基础设施层,对redis、mq等三方工具的对访问
    这一层主要完成和第三方插件数据的交互,完成数据转换并将数据传递到中间件,从中间件获取数据数据,并转换成业务需要的数据对象;
    d、responsitory层:仓储层,实现持久化对象到业务对象到转换和交互
    在领域设计里,数据库也是中间件的一种,是放在基础设施层的,但是基于现有开发模式以及数据库的重要性,我们应该强化这一层概念,将仓储层单独成模块,来实现数据持久化的相关逻辑。
    e、application层和domain层:核心业务实现模块
    在领域驱动设计中,application层不处理业务只用来编排业务和调用基础设施层的,domain则是核心业务实现的地方,目前我们对业务编排的概念还在探索中国,所以这一部分业务逻辑分层处理我们后续会继续更新讨论。

项目代码架构-业务分层和各层业务逻辑_第1张图片

4、参数统一封装返回

系统统一参数返回:BaseResult、PojoResult、CollectionResult、ListResult、MapResult、PageResult;BaseResult实现Serializable使结果对象可以序列化传输;其他结果对象均继承BaseResult,只是各自的返回值类型不同而已。

欢迎大家一块提意见讨论,我们也在继续摸索中;

你可能感兴趣的:(业务开发专栏)