将非纯函数转换为纯函数改进 - Scala


object IO {
def getHtmlFromWebsiteViaHttp(link: String, apiKey: String = ""): String = {
Http(link)
.param("access_token", apiKey)
.asString
.body
}
}
class SongService {
private def retrieveSongId(songName: String): Option[JsValue] = {
val formattedSongName = songName.replace(" ", "%20")
val searchLink = "https://api.genius.com/search?q=" + formattedSongName
//impure call
val geniusStringResponse = IO.getHtmlFromWebsiteViaHttp(searchLink, apiKey)
//Extra processing on geniusStringResponse
}
}

我目前的设计是我将有一个服务类,负责通过外部API获取一些信息。现在我明白了不可能有 100% 的纯函数。

我的问题:处理需要在 Scala/FP 中连接到外部 API 的情况的最佳方法是什么?目的是通过最小化不纯函数来获得最合适的"函数式编程风格">

目前,我正在将所有 API 调用封装在 IO 对象中。这足够合适吗?我看到了这种情况的单子的例子。在这种情况下,我应该加入 monad 样式吗?

这不是一个 FP 问题,因为我在 FP 方面没有看到您的代码有任何问题,但在我看来,您应该做的是使用依赖注入,这样,对于测试,您可以用测试类代替具有保证响应的IO。像这样:

abstract class IO {
def getHtmlFromWebsiteViaHttp(link: String, apiKey: String = ""): String
}
class IOImpl extends IO {
def getHtmlFromWebsiteViaHttp(link: String, apiKey: String = ""): String = {
Http(link)
.param("access_token", apiKey)
.asString
.body
}
}
class IOTestImpl extends IO {
def getHtmlFromWebsiteViaHttp(link: String, apiKey: String = ""): String = ??? //some test HTML
}

然后在您的服务中:

class SongService(io: IO) {
private def retrieveSongId(songName: String): Option[JsValue] = {
val formattedSongName = songName.replace(" ", "%20")
val searchLink = "https://api.genius.com/search?q=" + formattedSongName
val geniusStringResponse = io.getHtmlFromWebsiteViaHttp(searchLink, apiKey)
//Extra processing on geniusStringResponse
}
}

然后,当您实例化SongService时,在测试中IOTestImpl传递它,否则IOImpl。您可能会找到有关依赖关系注入和数据库访问对象的一些相关信息。

相关内容

  • 没有找到相关文章

最新更新