我应该在 Dao 还是 Service 的哪一层解析 Rest 客户端响应?

In Which Layer, Dao or Service, Should I Parse a Rest Client Response?

我有自己的服务调用第三方休息服务,该服务返回基于文本的 response.This 基于文本的响应不是正确的服务响应,需要针对内容和错误进行解析。出于讨论目的,假设无法更改第 3 方休息服务。

鉴于这些情况,我想知道我是否应该将解析连接到 dao 层或我的服务层 application.I 知道服务层应该包含您的所有业务逻辑,但我觉得如果我不在我泄漏的 Dao 层中进行解析。在这种情况下,出于 parsing/transformation 的目的,在 dao 中包含逻辑是否可以,还是应该在服务层中完成?

如有任何建议,我们将不胜感激。

public void MyDao {

     private RestTemplate restTemplate;
     private ResponseParser responseParser;

     public myDao(RestTemplate restTemplate, ResponseParser responsePaser){
          this.restTemplate = restTemplate;
          this.responseParser = responseParser;
     }

     public MyResponse sendRequest(MyRequest myRequest){
         ResponseEntity<String> responeEntity = restTemplate.exchange(...);
         String body = responseEntity.getBody();
         return responseParser.parse(body);
    }
}

public void MyDao {

     private RestTemplate restTemplate;

     public myDao(RestTemplate restTemplate, ResponseParser responsePaser){
          this.restTemplate = restTemplate;
     }

     public String sendRequest(MyRequest myRequest){
         ResponseEntity<String> responeEntity = restTemplate.exchange(...);
         return responseEntity.getBody();
    }
}

public void MyService {

     private MyDao myDao;
     private ResponseParser responseParser;

     public myDao(MyDao myDao, ResponseParser responsePaser){
         this.myDao = myDao; 
         this.responseParser = responseParser;
     }

     public MyObject process(MyRequest myRequest){
         String response = myDao.sendRequest(myRequest)
         return responseParser.parse(response);
    }
}

严格来说,Dao 层用于管理包含在持久性机制中的信息,例如:数据库、LDAP 等 因此,当您处理外部端点时,“包含”那个服务中的功能是一种使用更广泛的方法。

回答你的问题,第一个选项更好。

  1. 您正在将所需的业务逻辑包含到知道外部端点返回的 format/information 的 class 中。

  2. 使用上述对象的外部 classes 将管理一个众所周知的对象(而不是原始字符串值)

  3. 外部端点中的某些类型的升级(例如响应格式的更改)可以在您的 Dao 中得到更好的管理 class,而不会影响其他 class 使用它的人。

我的意见是放在DAO层。因为解析不是业务功能。 DAO 层也用于从数据库或其他第三方实体访问数据。因此,在我看来,从 DAO 层返回时使用正确的 POJO 格式的数据很有意义。

以下是我对设计的看法和看法。

  • DAO 是一种抽象持久性操作的模式,应仅用于持久性操作。
  • DAO 模式有助于从客户端的数据源中抽象出持久性 mechanism/operations 或数据访问操作,并且设计遵循 SRP,从而可以轻松过渡到新的持久性类型。并且更改 - 持久性机制/数据源的更改停留在 DAO 层中,而不是沸腾到服务层。
  • 服务层负责处理和计算对您的数据的业务操作。它使用 DAO/Repository/Client 来获取它需要操作的数据。

考虑到以上几点,以下是我对现有设计的看法以及我将如何做。

  • DAO,正如上面提到的 chrylis,是一个 数据访问对象 并且无论数据是从数据库还是通过 HTTP 获取都无关紧要。 Oracle 关于 J2EE 模式的 article 内容如下:

Use a Data Access Object (DAO) to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data.

进一步阅读:数据源可以是像 RDBMS 这样的持久存储,像 B2B 交换一样的外部服务,像 LDAP 数据库一样的存储库,或通过 CORBA Internet ORB 间协议 (IIOP) 或低级套接字访问的业务服务

  • 考虑到这些,我会从 DAO 进行调用,解析响应并将业务对象发送到服务。
  • 考虑到 SRP,服务不应知道通过 HTTP 进行的调用/从平面文件进行的数据库调用/读取。它应该知道的是,一旦我对数据进行查询,我就会从 DAO 中取回一个包含所需数据的对象。
  • 如果服务负责解析,如果明天数据源发生变化并且您拥有原位数据怎么办。所以现在您的 DAO 发生了变化,因为现在它与 DB 对话而不是发出 HTTP 请求。您不能再 return 支持 String 表示。您需要一个数据映射器并将返回某种对象表示形式,这意味着您的服务 class 也会发生变化。所以一个数据源的改变,不仅改变了你在DAO中的代码,而且归结到业务层,这破坏了SRP。
  • 这么说,开发时间不长,也不是软件工程背景(我知道数据访问对象只能来自数据存储,但感谢 chrylis 的评论让我阅读更多并思考两者之间的区别数据源和数据存储),我总是更喜欢将其命名为 Client -> RestClient 并进行调用并将我的数据库操作保持在 DAO/Repo。原因是,明天很容易阅读。一看 class 名称,就很容易理解它在做什么或 class 可能正在处理什么样的操作。

所以,是的,调用和解析应该发生在 DAO/Client。