代码层级规范的思考与实践

202 阅读4分钟

这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战

一.代码分层的由来

分层思想是计算机科学里最重要的一个思想,它将复杂的工作进行拆解,每层都忠于自己的目标。 最经典的就是网络的7层或者5层分层了。

在软件工程里,分层的思想就够重要了,可以做到合理的代码智能的拆分和复用。大概每位后端一开始学java写web服务时,都接触过经典框架。即 controller-service-dao处理。第一层做接口层,第二层写业务逻辑,第三层就是数据库操作。一开始大家对这个分层应该都没有很清晰的认知,也不知道为啥要这么分,代码其实写的也是五花八门。毕竟在学校里写的项目,几乎都是一锤子买卖,也不会有很复杂的迭代。所以代码只要能跑通没bug就成。

二.怎么才是好的分层

于我而言,在毕业前两年对代码结构的认知都还没有很清晰的认知,也仅仅是大家都说这么做,自己也跟着这么做。不过这时毕竟是公司生产级代码,结构已经相关规范了。这时自己有几个简单的认知,controller或者dubbo、job、mq consumer等这集中接入层,只做参数校验就好了。orm层一般使用mybatis,只处理数据库就好了。但对中间的service层,也没太清楚的认知。

在我工作第5年时,有幸作为两个独立领域微服务的owner和一个大接入层聚合web服务的参与者。慢慢理清楚领域的界限。

哪些代码应该写在领域内,哪些代码应该写入聚合层。虽然这个问题不在本文的探讨中,也多写两句。其实就一个标准。

A或者B是否其中一个服务的标准流程。或者A和B在一个领域里看,是否强耦合在一起的,如果不是,这个调用逻辑应该放在聚合层。

书回正文,代码结构分成其实在阿里规范里已经写的很清楚了

image.png

image.png 虽然不同团队的分层名字可能不同,但职能都是相近的。例如我经历的图中的service我们叫business。manager层我们叫service。

现在分层接口是contoller-business-servier-mapper

business允许调用service,单不允许调用mapper。service可以调用多个mapper。

controller做参数校验。mapper就是sql的映射。允许存在updateById这种万能写操作方法。

service是自己领域内核心能力的聚合,例如事务下的多表操作。核心流程发送mq等。都聚合在service层,保证没有关键操作遗漏。service也是自己领域服务的核心逻辑。

此层写操作不在允许暴露updateById这种万能无业务语义的写法。一些udpate操作都要声明含有语义的方法,写明是更新***功能的方法。

business层就是聚合逻辑了,领域服务也是允许调用其他服务的。一般在business层写。

三.为什么要分层

我是经历过一个不好的分层项目,大概就是所有功能都在一个项目里,而且同一个功能,实现方式多种的项目。

后期要迭代一个功能,是真的难,光缕清所有写入点,就已经很痛苦了。

而且有些领域服务的操作是会影响很多团队的,例如我项目的核心模型的声明周期,是有不少其他服务关注的。因此我得保准消息和数据库的准确性。不能出现了操作了数据库,消息没发。

因此一定要对这种操作进行严格的耦合。避免只操作db,不发消息的方法被调用。用来private等关键字。

如何保证自己的代码不会被后人称为屎山代码,合理清晰简单的规范是很重要的。