我在几个项目中使用Datomic,是时候将所有常用代码移动到一个小型实用程序库中。
一个挑战是处理大多数操作所依赖的共享数据库uri
,但必须由项目使用库设置。我想知道是否有一种完善的方法来做到这一点。以下是我想过的一些替代方案:
删除库中的uri
符号并将uri作为参数添加到访问数据库的每个函数
在初始化函数中通过alter-var-root
或类似机制对其进行更改
将其作为动态var *uri*
保存在库中,并覆盖希望小的适配器层中的值,如
(def my-url ... bla ...)
(defn my-fun [args] (with-datomic-uri my-uri (应用library / my-fun args))
将uri
保留为库中的原子
答案 0 :(得分:4)
Stuart Sierra最后一次Clojure / West发表了一篇名为Clojure in the Large的演讲,讨论了更大的Clojure应用程序的设计模式。
其中一个是你描述的问题。
总结有关手头问题的提示:
1清除构造函数
所以你有一个定义良好的初始状态。
(defn make-connection [uri]
{:uri uri
...}
2明确依赖
(defn update-db [connection]
...
3测试更容易
(deftest t-update
(let [conn (make-connection)]
(is (= ... (update-db conn)))))
4更安全重装
(require ... :reload)
将 uri 保留在稍后要绑定的变量中是很常见的,但引入了隐藏的依赖关系,也假定body
在单个线程上开始和结束。
观看演讲,了解更多有关设计的提示。
答案 1 :(得分:3)
我的感觉是保持大多数数据组代码尽可能没有隐式状态。
让查询函数获取数据库 值 。写函数(transact
)采用数据库连接。这最大化了潜在的重用并避免了隐含的假设,例如只与一个数据库连接交谈,或者无意中隐式地将查询函数硬编码为仅处理当前数据库值 - 而不是过去(as-of
)或“future”({{1数据库值。
为库的标准用例协调单个公共连接然后成为小额外命名空间的工作。使用原子在这里有意义来保持uri或连接。如果手动编写和传递连接和数据库值是一件麻烦事,那么一些便利宏(可能称为with
和with-connection
可以包装主库函数。