为Clojure协议提供多种实现 [英] Provide multiple implementations for a Clojure protocol

查看:72
本文介绍了为Clojure协议提供多种实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个命名空间,可以公开与数据相关的常见功能(获取图像插入用户)。然后,我有两个具有相同功能并以不同方式实现它们的数据库后端。他们照原样实现了接口。每个后端都包含在一个命名空间中。

I have a namespace that exposes common data-related functions (get-images, insert-user). I then have two database backends that have those same functions and implement them differently. They implement the interface as it were. Each backend is contained within a namespace.

我似乎无法找到一个好的解决方案。

I can't seem to be able to find a good solution on how to accomplish this.

我尝试动态加载 ns ,但是没有运气。一旦执行(:require [abc:as x]) x 就不是真实值。

I tried dynamically loading the ns but no luck. Once you do (:require [abc :as x]), the x isn't a real value.

我尝试使用 defprotocol deftype 但这是各种各样的之所以很奇怪,是因为还需要导入 deftype 中的函数,这对我来说一团糟。

I tried using defprotocol and deftype but that's all kinds of weird because the functions in the deftype need to be imported, too and that messes everything up for me.

推荐答案

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

I don't see why protocols are not sufficient?

在ns data.api中:

In ns data.api:

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

在ns data.impl1中:

In ns data.impl1:

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

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

与ns data.impl2中的内容相同。

Same thing in ns data.impl2.

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

Then when you go to use a particular db, just create the correct record:

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

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

这篇关于为Clojure协议提供多种实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆