我应该在哪个层、Dao 或服务中解析 Rest 客户端响应? [关闭]
Posted
技术标签:
【中文标题】我应该在哪个层、Dao 或服务中解析 Rest 客户端响应? [关闭]【英文标题】:In Which Layer, Dao or Service, Should I Parse a Rest Client Response? [closed] 【发布时间】:2020-11-22 07:13:26 【问题描述】:我有自己的服务调用第三方 rest 服务,该服务返回基于文本的响应。此基于文本的响应不是正确的服务响应,需要解析内容和错误。出于讨论的目的,假设第 3 方休息服务不能更改。
鉴于这些情况,我想知道是否应该将该解析连接到应用程序的 dao 层或服务层。我知道服务层应该包含您的所有业务逻辑,但我觉得如果我不这样做在我泄漏的 Dao 层中进行解析。在这种情况下,是否可以在 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);
【问题讨论】:
对您问题的每一个答案肯定都是基于与个人程序员偏好相关的意见。因此,在我看来,由于单一职责原则,单独的解析逻辑更好。 对于 SRP,它声明一个类应该只有一个改变的理由。我会说在 dao 中包含解析是可以的,因为如果其余响应的格式发生变化,您将需要更改它的解析方式。因此它们本质上是耦合的,不是吗? 【参考方案1】:严格来说,Dao 层用于管理包含在持久性机制中的信息,例如:数据库、LDAP 等。因此,当您处理外部端点时,在服务中“包含”该功能是一种更广泛使用的方法。
回答您的问题,第一个选项更好。
您将所需的业务逻辑包含在知道外部端点返回的格式/信息的类中。
使用上述类的外部类将管理一个众所周知的对象(而不是原始字符串值)
可以在您的 Dao 类中更好地管理外部端点中的某些类型的升级(例如响应格式的更改),而不会影响使用它的其他类。
【讨论】:
“DAO”代表“数据访问对象”。如果拥有数据的系统碰巧是通过 HTTP 而不是 JDBC 访问的,这不会改变关系的性质,使用RestTemplate
的 DAO 与使用 JdbcTemplate
的 DAO 一样合理。
我自己和我的一位导师对此有过几次“好脾气”的争论哈哈。我倾向于同意医生的观点,即它属于服务或更好的是它自己的 RestClient 类。我相信这是因为严格来说,DAO 定义确实适用于“持久性”机制,并且这个特定的休息服务不会持久化任何东西,只是解析并返回响应。现在,如果我调用一个有 crud 操作的 rest 服务,那么我会说它属于 DAO。我想这一切都归结为你想要解释规则的严格程度。【参考方案2】:
这是我对设计的看法和看法。
DAO 是一种抽象持久性操作的模式,应仅用于处理持久性操作。 DAO 模式有助于从客户端的数据源中抽象出持久性机制/操作或数据访问操作,并且设计遵循 SRP,从而轻松过渡到新的持久性类型。而你的持久化机制/数据源的变化,停留在 DAO 层,而不是服务层。 服务层负责处理和计算数据上的业务操作。它使用 DAO/Repository/Client 来获取操作所需的数据。考虑到以上几点,以下是我对现有设计的看法以及我将如何做。
DAO,正如上面提到的 chrylis,是一个数据访问对象,无论数据是从数据库中还是通过 HTTP 获取都无关紧要。 Oracle 关于 J2EE 模式的article 内容如下:使用数据访问对象 (DAO) 来抽象和封装对数据源的所有访问。 DAO 管理与数据源的连接以获取和存储数据。
它进一步写道:数据源可以是像 RDBMS 这样的持久存储,像 B2B 交换这样的外部服务,像 LDAP 数据库这样的存储库,或者通过以下方式访问的业务服务CORBA Internet Inter-ORB 协议 (IIOP) 或低级套接字。
考虑到这些,我会从 DAO 进行调用,解析响应并将业务对象发送到服务。 考虑到 SRP,服务不应该知道通过 HTTP 进行的调用/进行的 db 调用/从平面文件中读取。它应该知道的是,一旦我对数据进行查询,我就会从 DAO 中取回一个包含所需数据的对象。 如果服务负责解析,如果明天数据源发生变化并且您拥有原位数据怎么办。所以现在你的 DAO 发生了变化,因为它现在与 DB 对话,而不是发出 HTTP 请求。你不能再返回一个字符串表示。您需要一个数据映射器并将某种对象表示发回,这意味着您的服务类也发生了变化。因此,数据源的一次更改,不仅会更改您在 DAO 中的代码,还会涉及业务层,这会破坏 SRP。 这么说,不是长期开发,也不是软件工程背景(我理解数据访问对象只能来自数据存储,但感谢 chrylis 的评论让我阅读更多并思考数据之间的区别-源和数据存储),我总是更喜欢将其命名为 Client -> RestClient 并进行调用并将我的数据库操作保留到 DAO/Repo。原因是,明天很容易阅读。一看类名,就很容易理解它在做什么或该类可能正在处理什么样的操作。所以,是的,调用和解析应该发生在 DAO/Client 中。
【讨论】:
【参考方案3】:我的意见是放在 DAO 层。因为解析不是业务功能。此外,DAO 层用于访问来自 DB 或其他第三方实体的数据。因此,在我看来,从 DAO 层返回时以正确的 POJO 格式保存数据是很有意义的。
【讨论】:
以上是关于我应该在哪个层、Dao 或服务中解析 Rest 客户端响应? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章