我正在开发一个Clojure应用程序,我们希望能够对遗留数据库和新数据库起作用。我们的想法是在一个文件中定义通用数据库API函数,该文件根据环境设置映射到旧数据库API或新数据库API中的相应函数。作为Clojure的新手,这就是我想出来的。
(ns app.db-api
(:require [app.old-api]
[app.new-api]
[app.config :refer [env]]))
;; Define placeholder functions that are later interned to point at either
;; new or old API. The corresponding functions are defined and implemented in
;; old-api and new-api
(defn get-user [user-id])
(defn create-user [user-name])
;; Iterate through defined functions in this namespace and intern
;; them to the corresponding functions in the new or old API, as
;; configured by the :db-api environment variable
(doseq [f (keys (ns-publics *ns*))]
(let [x (symbol f)
y (eval (symbol (str "app." (env :db-api) "/" f)))]
(intern *ns* x y)))
使用此功能,对db-api/get-user
的调用将映射到old-api/get-user
或new-api/get-user
,具体取决于:db-api
环境变量中的设置。
一个明显的警告是db-api必须复制所有API函数的声明,并且API函数不能分布在多个文件上,但必须驻留在db-api,old-api和new-api中。此外,我们使用conman,conman/connect!
和conman/bind-connection
也必须连接/绑定到不同的数据库/ sql文件,具体取决于是使用旧API还是新API。
问题是这是否是一个合理的解决方案,还是有更好的方法来实现同一目标?感谢任何评论。
答案 0 :(得分:1)
您可以使用多方法。 https://clojuredocs.org/clojure.core/defmulti
(defmulti get-user (fn [user-id] (grab-env-var :db-api)))
(defmethod get-user :old-api [user-id]
(use-old-api user-id))
(defmethod get-user :new-api [user-id]
(use-new-api user-id))