2016-10-28 11 views
1

私はClojureアプリケーションで、従来のデータベースと新しいデータベースを扱いたいと思っています。この考え方は、一般的なデータベースAPI関数を、環境設定に応じて古いデータベースAPIまたは新しいデータベースAPIの対応する関数にマップする1つのファイルで定義することです。 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への呼び出しは:db-api、環境変数の設定に応じて、old-api/get-userまたはnew-api/get-userにマップされます。

db-apiはすべてのAPI関数の宣言を複製する必要があり、API関数は複数のファイルにまたがることはできませんが、db-api、old-api、およびnew-apiに存在する必要があります。また、conmanを使用しており、conman/connect!conman/bind-connectionは、古いAPIと新しいAPIのどちらを使用するかによって、異なるデータベース/ sqlファイルに接続/バインドする必要があります。

質問はこれが妥当な解決策であるか、同じ目標を達成するためのよりよい方法があるかどうかです。コメントに感謝します。

答えて

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)) 
関連する問題