为Clojure协议提供多种实现

时间:2014-03-07 17:52:56

标签: clojure

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

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

我尝试动态加载ns,但没有运气。完成(:require [abc :as x])后,x不是真正的值。

我尝试使用defprotocoldeftype,但这种情况很奇怪,因为deftype中的函数也需要导入,并且会让我感到烦恼。

对此有一些惯用的解决方案吗?

1 个答案:

答案 0 :(得分:8)

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

在ns data.api中:

(ns data.api)
(defprotocol DB
  (get-images [this]) 
  (insert-user [this]))

在ns data.impl1:

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

(defrecord Database1 [connection-params]
  DB
  (get-images [_] ...)
  (insert-user [_] ...))

ns data.impl2中的相同内容。

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

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

(defn use-db []
  (let [db1 (->Database1 {})]
    (get-images db1)))