在关于仿函数的 Real World Ocaml Chapter 9 中:



但我无法理解这个想法。
我还查看了有关 DI 的 Wikipedia - 但实际上我没有发现与测试和模拟目的的关系。

最佳答案

Dependency injection 是一种软件工程技术,其目的是减少程序的两个子系统之间的相互依赖性。这项技术的一个非常重要的细节是它涉及的不是两个,而是三个子系统:

  • 服务,
  • 使用
  • 的客户端
  • 注入(inject)器,其职责是为客户端准备服务。

  • 后一个子系统及其职责是一个经常被忽视但至关重要的细节:这意味着客户端对服务的了解与其公共(public)接口(interface)一样少,这意味着人们可以轻松地使用模拟服务来测试客户端。

    假设我们编写了一个通过网络与键值存储通信的应用程序。键值存储具有以下签名:
    module type AbstractKeyValueStoreService =
    sig
       exception NetworkError
       type t
       val list : t -> string
       val find : t -> string -> string option
       val set : t -> string -> string -> unit
    end
    

    如果我们通过 AbstractKeyValueStoreService 类型的模块将我们的客户端代码编写为客户端参数,我们可以在使用 set 函数时通过提供模拟服务来测试我们的应用程序对网络错误的弹性,而无需实际创建网络错误:
    module KeyValueStoreServiceFailingOnSet =
    struct
      exception NetworkError
      type t = unit
      let list () = [ "a"; "b"]
      let find = function
        | "a" -> Some("x")
        | "b" -> Some("y")
        | _ -> None
      let set _ _ = raise NetworkError
    end
    

    如果我们的客户端被编写为由 AbstractKeyValueStoreService 类型的模块参数化的仿函数,则很容易为这个软件组件编写测试,其中模拟服务遵循与客户端或多或少复杂的交互脚本。

    使用模块作为参数可能不是一个“惊天动地的想法”,但重要的是要意识到如何使用这个想法来解决重要的软件工程问题。这就是“真实世界 OCaml”的作者们所做的。

    关于dependency-injection - ocaml,仿函数 : dependency injection,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35110857/

    10-12 02:42
    查看更多