Java中controller层和service代码应该怎么分配?

相信大家对Spring MVC的架构都比较清楚了。Spring MVC是Spring框架的一部分,Spring框架成为Java EE开发主流框架后,Spring开发小组又在Spring框架的基础上推出了MVC架构,主要用于支持WEB应用程序的开发。MVC是Model(模型,也称为数据模型)、View(视图)、Controll(控制器)三个英文单词首字母的缩写。从MVC组合的三个单词也可以看出,MVC是一种设计模型,它使用控制器将数据模型和视图进行分离,也就是将视图和数据解耦。这样的好处是后端处理的数据模型和前端视图显示的数据格式无关,实现一个数据模型可以对应多个视图以不同的方式来展现数据,当数据模型或视图发生变化时,相互之间的影响也会降低到最低。实际上MVC是各有其责,分层清晰,逻辑较为清楚。

当下,随着微服务架构的不断流行。基于RPC框架和HTTP协议实现的微服务架构越来越受到各大公司的欢迎。其中比较典型的有:

Dubbo,最早由阿里开发的远程RPC框架,在国内的生态发展的非常不错,和Spring Cloud基本上二分微服务界。

Spring Cloud,大名鼎鼎的Spring框架中的一员,提供了微服务一系列的解决方案,从注册中心、负载均衡、服务熔断等,可以方便的进行微服务架构的开发。

顺带讲一句,二者的区别。笔者看来,比较直接的不同就是,Dubbo使用RPC通讯协议,Spring Cloud支持http协议,在带宽上dubbo具有一定的优势,但是随着网络带宽的发展,可以忽略不计;还有一点不同则要从CAP原则方面进行说明。CAP原则,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

Dubbo 实践通常以ZooKeeper 为注册中心(Dubbo 原生支持的Redis 方案需要服务器时间同步,且性能消耗过大)。针对分布式领域著名的CAP理论(C——数据一致性,A——服务可用性,P——服务对网络分区故障的容错性),Zookeeper 保证的是CP ,但对于服务发现而言,可用性比数据一致性更加重要 ,而 Eureka 设计则遵循AP原则 。

回归正题,我们今天要说的是关于controller层和service层的代码逻辑分配问题。基于上面的介绍,我们可以看出,服务调用可以通过两种方式,一种是基于HTTP协议,另一种就是RPC框架。HTTP协议可以实现接口跨平台调用,一般可作为对外接口提供的实现方式;而RPC可作为对内的服务暴露实现方式。RPC可以直接通过暴露Service接口来实现,HTTP一般需要制定接口的具体路径(通过Controller层实现)。

最近笔者在进行一些接口重构方面的工作,原有的HTTP服务,改造成为公司原生的微服务架构。所有的接口都通过RPC来进行实现,需要对外的接口则通过HTTP协议实现。这里我遇到了一个问题:相同的代码,我们可以写在controller层,也可以写在service层。例如:参数校验、结果聚合等。接口的输入和输出参数应该怎么去写。

这里谈谈个人的一些想法,不一定正确,希望大家一起讨论:

1、基于HTTP协议实现的接口,应该对返回结果进行统一封装;返回结果需要包含以下内容:请求状态,请求结果(成功),失败原因(代码和消息内容);

2、基于RPC框架的服务,可不对返回结果进行统一封装。一般都是内部的结果调用,如果在封装的话,对内容解析也会比较麻烦;可以通过异常捕捉的方式来实现;

3、接口的入参(两个以上)和返回值应该封装成一个对象,降低服务调用者和服务之间的耦合性。

4、参数校验,Controller和Service层都需要,返回结果的聚合可在Controller中实现

5、业务相关逻辑放在Service中,使得Service接口能够成为一个完整的业务逻辑;

 

以上即是个人的一些想法和总结,希望大家可以一起交流。

你可能感兴趣的:(微服务)