为Clojure协议提供多种实现

Hon*_*rny 4 clojure

我有一个名称空间,公开与公共数据相关的函数(get-images,insert-user).然后,我有两个具有相同功能的数据库后端,并以不同的方式实现它们.他们实现了接口.每个后端都包含在命名空间中.

我似乎无法找到一个如何实现这一目标的良好解决方案.

我尝试动态加载ns但没有运气.一旦你这样做(:require [abc :as x]),这x不是一个真正的价值.

我试着用defprotocoldeftype但这就是各种奇怪的,因为在功能deftype需要进口,也和这对我弄乱了一切.

这有什么惯用的解决方案吗?

Ale*_*ler 8

我不明白为什么协议不够用?

在ns data.api中:

(ns data.api)
(defprotocol DB
  (get-images [this]) 
  (insert-user [this]))
Run Code Online (Sandbox Code Playgroud)

在ns data.impl1中:

(ns data.impl1
  (:require [data.api :refer :all]))

(defrecord Database1 [connection-params]
  DB
  (get-images [_] ...)
  (insert-user [_] ...))
Run Code Online (Sandbox Code Playgroud)

ns data.impl2中的内容相同.

然后,当您使用特定的数据库时,只需创建正确的记录:

(ns data.user
  (:require [data.api :refer :all])
            [data.impl1 :refer (->Database1)])

(defn use-db []
  (let [db1 (->Database1 {})]
    (get-images db1)))
Run Code Online (Sandbox Code Playgroud)

  • 该线程可能早于Clojure 1.4.从1.4开始,defrecord导致创建位置(例如 - > Database1)和map(例如map-> Database1)构造函数,这是构造新记录的首选方法.使用它们时,不需要导入基础记录类,只需在构造函数本身中引用即可. (2认同)