gpt4 book ai didi

web-services - 在具有依赖关系的 Scala 代码中调用外部服务

转载 作者:行者123 更新时间:2023-12-04 04:41:37 25 4
gpt4 key购买 nike

此时我的设计遇到了一个重大问题。我的方法试图完成以下任务:

  1. 将传入的对象插入数据库。
  2. 从插入中获取自动递增的 ID,并使用它与对象一起调用 webservice1。
  3. 从 webservice1 获取结果并使用原始对象和来自 webservice1 的一些响应调用 webservice2。
  4. 合并 webservice1 和 2 的结果并将其写入数据库。
  5. 从最后一次插入中获取生成的自动递增 ID,并使用最终会导致操作成功或失败的原始对象调用 webservice3。

我想以灵活的方式设计它,因为需求在不断变化,我不想根据任何变化继续修改我的逻辑。我确实意识到一些变化是不可避免的,但我想尽量减少损害并尊重开闭原则。

我最初的想法如下:

def complexOperation(someObject:T) = 
dbService.insertIntoDb(someObject) match {
case Left(e:Exception) => Left(e)
case Right(id:Int) => webService.callWebService1(id,someObject) match {
case Left(e:Exception) => Left(e)
case Right(r:SomeResponse1) => webService.callWebservice2(r,someObject) match {
case Left(e:Exception) => webService.rollbackService1();Left(e)
case Right(context:ResponseContext) => dbService.insertContextIntoDb(context) match {
case Left(e:Exception) => Left(e)
case Right(id:Int) => webService.callWebservice3(id,someObject) match {
case Left(e:Exception) => webService.rollbackService3();Left(e)
case Right(r:Response) => Right(r)
}
}
}
}

如您所见,这是一团乱麻。如果事情失控,我既不能对它进行单元测试,也不能扩展它,也不能很容易地调试它。这段代码达到了它的目的,但如果能获得一些关于我应该如何重构它以使继承我的代码的人的生活更轻松的想法,那将是很棒的。

谢谢

最佳答案

看看scala.util.Try .它在 Scala 2.10 中可用,您可能会也可能不会选择它,但它的想法非常适合您的场景。

您在代码示例中所拥有的就是我喜欢称之为嵌套“金字塔”的东西。最好的解决方案是尽可能使用平面映射。但显然,当您在每一步都遇到诸如 Either[Exception, Result] 之类的内容时,这显然是个问题。这就是 Try 的用武之地。Try[T] 本质上是 Either[Exception, T] 的替代品,它附带了所有flatMap- 满足您的需求。

假设您可以更改那些 webService 调用的返回类型,或者提供一些从 Either[Exception, Result]Try[Result] 的隐式转换,你的代码块会变得更像......

for {
id <- dbService.insertIntoDb(someObject)
r <- webService.callWebService1(id,someObject)
context <- webService.callWebservice2(r,someObject)
id2 <- dbService.insertContextIntoDb(context)
response <- webService.callWebservice3(id,someObject).recoverWith {
case e: Exception => webService.rollbackService3(); Failure(e)
}
} yield response

电梯在net.liftweb.common.Box中有类似的机制.它类似于 Option,但也有一个异常容器。

编辑:看起来您可以使用Eitherleftright 方法,并且它将让您使用 flatMap-ing 几乎完全按照我在 Try 中描述的方式。唯一的区别是最终结果是 Either[Exception, Result] 而不是 Try[Result]。查看LeftProjection有关详细信息/示例。

关于web-services - 在具有依赖关系的 Scala 代码中调用外部服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13105020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com