印象中有些日子没有写文章了,最近一直在放飞自我,今天和大家分享的一些在搭建脚手架和编程中的一些实践原则。所有目标都是“清晰架构分层”。
使用统一的依赖管理
这种方式是基于我多年来的实践。最开始我也将项目类库及其版本随意的管理,大部分情况下它们能够正常的工作,遇到版本升级和依赖冲突就很头疼。于是模仿一些知名开源的依赖的管理,定制自己的BOM,就像这样:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.felord.</groupId>
<artifactId>my-bom</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这样你的依赖管理将非常清晰, 在升级第三方依赖或者增减依赖的时候,只需要升级这个依赖的版本即可。
约定大于配置
众所周知Spring Boot的一个重要的特点就是约定大于配置。但是我在一些开源脚手架和一些项目中看到的却不是延续这一思想,用了大量的代码实现了一些可有可无的自定义配置。比如我在某个项目的Spring Security依赖中看到,自定义了所有的默认配置,将简单的问题复杂化却收效甚微,默认提供的PasswordEncoder不好用吗?能复用就复用,用最少的配置解决问题。
MVC分工应该专注和简洁
控制器
关于控制器,也就是Controller,它更多的角色应该是一个协调者和委托者,而不承担具体业务逻辑的执行工作。控制器应该专注于HTTP层面的功能,比如参数的绑定处理,序列化和反序列化,具体的业务委托给下游的服务层。
还有一个点就是接口的命名风格要一致,还要有层次感和语义化。比如/api/user/{id}、/api/order/{id}、/api/order/user/{id}。
服务层
服务层我遇到的问题就是出口分散问题,很多同学订单的出口可能根据某些原因分散在其它的服务层接口,而不是集中于OrderService中。大多数情况下,我觉得集中管理有利于后续的迭代维护,保证了各个Domain业务之间的相对独立性。
还有一点,同一个Spring容器下服务层之间的相互调用容易引起依赖循环问题,比如UseService要调用OrderService查询订单,而OrderService可能又依赖了UserService,最好的办法是服务层之间尽量不相互调用,去调用持久层的OrderMapper,当然一些功能性的接口服务例外,例如短信服务、三方接口这一类。
说到短信服务、三方接口,这一类稳定的业务功能建议作为类库集成,既方便管理又可重用。
工具类
Spring内部的工具类和apache common包的工具类已经足够应付大部分情况,如果真的不满足再考虑去写工具类,工具类解决的一定是局部问题,不要把业务功能相关的东西封装成工具类。