【发布时间】:2013-06-05 04:10:48
【问题描述】:
我正在尝试将http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded 的想法实施到我的代码库中。
我有一个 dao 层,我现在需要传入一个数据库以避免全局状态。让我失望的一件事是这句话:
任何需要这些组件之一的功能都必须将其视为 范围。这并不像看起来那么繁琐:每个函数 最多得到一个额外的参数,提供它所在的“上下文” 运作。该上下文可能是整个系统对象,但更多 通常会是一些子集。通过明智地使用词法闭包, 额外的参数从大多数代码中消失了。
我应该在哪里使用闭包以避免每次调用都传递全局状态?一个示例是在 dao 层中创建一个 init 函数,如下所示:
(defprotocol Persistable
(collection-name [this]))
(def save nil)
(defn init [{:keys [db]}]
(alter-var-root #'save (fn [_] (fn [obj] (mc/insert-and-return db (collection-name obj) obj WriteConcern/SAFE)))))
这样我可以像这样从系统/启动函数启动我的 dao 层:
(defn start
[{:keys [db] :as system}]
(let [d (-> db
(mc/connect)
(mc/get-db "my-test"))]
(dao/init d)
(assoc system :db d)))
这行得通,但感觉有点恶心。有没有更好的办法?如果可能的话,我想避免强制我的 dao 层的客户端每次使用函数时都必须传递数据库。
【问题讨论】: