前面几篇blog主要介绍了DDD落地架构及业务建模战术,后续几篇blog会在此基础上,讲解具体的架构实现,通过完整代码demo的形式,更好地将DDD的落地方案呈现出来。本文是架构实现讲解的第一篇,主要介绍了DDD的User Interface层的实现,详细讲解了controller、dto的职责和实现,已经UI层使用到的公共组件:CheckLogin、Loging、Validation的职责和实现细节。文末附有github地址。相比于《领域驱动设计》原书中的航运系统例子,社交服务系统的业务场景对于大家更加熟悉,相信更好理解。本文是【DDD】系列文章的其中一篇,其他可参考:使用领域驱动设计思想实现业务系统

  User Interface层是用户接口层,为用户/调用方提供可访问的接口,我们简称为“UI”层。在 “【DDD】领域驱动设计实践 —— 框架实现” 一文中,我们将dto、controller归入了UI层。同时,在UI层中,我们还会去使用infrastructure层中的validation、logging、checkLogin等公共组件完成一些通用的动作。接下来我们将逐一讲解。

Controller

controller是公司前台

  这里的controller承担这一个请求受理的角色,就像是一个公司的前台,接受不同的请求(人员来访、电话咨询、快递/信件签收等等),必要时还会对不同的请求进行权限校验,以防坏人捣蛋(比如:查验来访者的身份,确认被访问者是否真有其人);并将不同格式的请求转换为通用的请求格式(用标准的邮件/电话/短信通知责任人);将请求转发到对应的负责人(可能是将电话转接给负责人,也可能是将应聘者介绍给面试官,还可能是叫某个程序猿出来取快递);到最后还会将来访者登录在案,必要时,还会通过前台告知具体的处理结果(告知电话咨询者其要求是否能得到满足,告知来访者他要找的人没有上班等)。

controller的职责

  类比与前台工作,我们可以发现controller有如下职责:

  •   接受请求;
  •        请求格式校验及转换;
  •   权限校验;
  •   路由请求;
  •   记录请求;
  •   回复响应;

controller的实现

  在示例代码中,我们使用spring-mvc框架实现,controller就直接使用spring-mvc中的controller层完成。对应到上述职责分别有如下组件完成:

  •   接受请求 —— Spring-MVC的DispatcherServlet组件完成;
  •        请求格式校验及转换 —— 格式校验遵循java Validation规范,使用Hibernate的validator组件完成;最终会被转换为DTO组件,并在DTO组件中落地validation,放到后面专门讲解;
  •   权限校验 —— 自实现的CheckLogin组件完成;放到后面专门讲解;
  •   路由请求 ——  Spring-MVC的@RequestMapping组件完成;
  •   记录请求 —— 自实现的Loggin组件完成;放到后面专门讲解;
  •   回复响应 —— Spring-MVC的@ResponseBody组件完成;

BaseController

  在实际编码中,发现所有的controller会有一些公共的行为,比如异常处理,封装响应dto,我们将这些行为抽象出来,放在BaseController中,所有的业务Controller继承这个基础类。

类图

 【DDD】领域驱动设计实践 —— UI层实现

 

 代码示例

 

 1 public class BaseController {
 2 
 3     private static Logger logger = LogManager.getLogger(BaseController.class);
 4     
 5     @Autowired
 6     private ApplicationUtil applicationUtil;
 7     
 8     @Autowired
 9     private ExceptionHandler exceptionHandler;
10 
11     /**
12      * format 失败 response。
13      * @param e
14      * @return
15      */
16     protected ResponseDto formatErrorResponse(final Exception e) {
17         ResponseDto responseDto = new ResponseDto();
18         //将response 的data body置为空
19         responseDto.setBody(null);
20 
21         //依据异常类型进行分别处理,将异常信息转义为用户友好的提示信息
22         Map<String, String> exceptionMap = exceptionHandler.handle(e);
23         responseDto.setReturnCode(exceptionMap.get("errorCode"));
24         responseDto.setReturnMsg(exceptionMap.get("errorMsg"));
25         logger.debug("Response is: "+responseDto);
26         return responseDto;
27     }
28     
29     
30     /**
31      * format成功的response
32      * @param responseBody
33      * @return ResponseDto
34      */
35     protected ResponseDto formatSuccessResponse(ResponseBody responseBody) {
36         ResponseDto responseDto = new ResponseDto();
37         //设置返回码和返回信息为成功
38         responseDto.setReturnCode(ReturnCode.SUCCESS);
39         responseDto.setReturnMsg(applicationUtil.getReturnMsg(ReturnCode.SUCCESS));
40         
41         //将response 的data body置为实际的业务body
42         responseDto.setBody(responseBody);
43         logger.debug("Response is: "+responseDto);
44         return responseDto;
45     }
46     
47     
48 }
BaseController.java

相关文章:

  • 2022-12-23
  • 2022-01-01
  • 2022-12-23
  • 2021-11-21
  • 2022-12-23
  • 2021-07-17
猜你喜欢
  • 2021-07-02
  • 2021-04-20
  • 2022-12-23
  • 2021-08-29
  • 2021-12-25
  • 2021-10-29
相关资源
相似解决方案