我正在开发一个Clojure应用程序,我们希望它能够处理遗留数据库和新数据库。其思想是在一个文件中定义通用数据库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。
问题是,这是否一个合理的解决方案,还是有更好的方法来实现同样的目标?感谢您的评论。
发布于 2016-10-29 13:59:45
您可以使用多重方法。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))https://stackoverflow.com/questions/40314056
复制相似问题