想象一下OCaml中的一个库,它可能需要将数据存储在某个地方.这个持久层可以用不同的库(sqlite,MySQL,PostgreSQL等)实现.并且根据存储的具体技术,它可能提供不同的功能和性能保证.
有哪些方法可以管理此类库的外部依赖项?假设我是用MySQL开发的,我不想在sqlite上引入编译时和运行时依赖.
在C++中,我可能会使用抽象接口,并将具体逻辑放入有条件地包含在我的项目中的模块中(取决于配置开关).我很好奇,任何人都会在OCaml中接近同样的任务.
您可能会定义一个模块类型来抽象所有实现.例如
module type DB =
sig
type t
type results
val execute : t -> string -> results
...
end
Run Code Online (Sandbox Code Playgroud)
然后,您将编写代码以将此模块类型的实现作为参数:
module MyProg (D : DB) = struct
let run db =
let r = D.execute db "SELECT ..." in
...
end
Run Code Online (Sandbox Code Playgroud)
对于图书馆来说,这就是你所需要的.对于可执行程序,您需要一个单独的main函数来连接到某个实际的数据库,这可能是特定于数据库的,但其余的代码只使用了抽象DB.
(当然,你使用的API比这个基于字符串的API更好.这只是一个简单的例子.)