ocaml,Functors:依赖注入

Pie*_* G. 4 ocaml dependency-injection

真实世界Ocaml第9章关于仿函数:

依赖注入

使系统的某些组件的实现可以交换.当您想要模拟系统的某些部分以进行测试和模拟时,这尤其有用.

但我没有理解这个想法.我还看了维基百科有关DI的信息 - 但实际上我并没有通过测试和模拟目的来捕捉这些关系.

Mic*_*ald 6

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

  • 一项服务,
  • 使用a的客户端
  • 注射器,其职责是为客户准备服务.

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

假设我们编写了一个通过网络与键值存储进行通信的应用程序.键值存储具有以下签名:

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
Run Code Online (Sandbox Code Playgroud)

如果我们写我们的客户端代码,通过类型的模块,客户parametrise AbstractKeyValueStoreService我们可以使用测试时,我们的应用程序网络错误的弹性设定功能通过只是提供了一个嘲笑的服务,而无需实际创建的网络错误:

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
Run Code Online (Sandbox Code Playgroud)

如果我们的客户端是由类型为AbstractKeyValueStoreService的模块进行参数化编写的,那么很容易为该软件组件编写测试,其中模拟服务遵循与客户端或多或少复杂的交互脚本.

使用模块作为参数可能不是一个"惊天动地的想法",但重要的是要知道这个想法如何用于解决重要的软件工程问题.这就是"真实世界OCaml"的作者似乎所做的.