2

まだ clojure を学んでいて、clojure とプロトコルに頭を悩ませる実験をしています。私の主な質問は、データベースに特定のデータ型を追加するためのよりクリーンな方法を提供するために、低レベルのデータベース相互作用を抽出する正しい方法は私のコードですか?

(defn- db-insert
 [table record]
 "Inserts record based on table/record map"
 (sql/with-connection
  rosay-db
   (sql/transaction
    (sql/insert-record table record))))

;; public interface
(defprotocol DBFactory
  (add-item [_] "Adds item to db"))

(defrecord Page [name description keywords frontpage client_id pages_type_id]
  DBFactory
  (add-item [_]
   (db-insert :pages {:name name
                              :description description
                              :keywords keywords
                              :frontpage frontpage
                              :client_id client_id
                              :pages_type_id pages_type_id})))

(defrecord Client [username password email domain]
 DBFactory
  (add-item [_]
   (db-insert :clients {:username username
                        :password password
                        :email email
                        :domain domain})))

次に、私の nrepl で次のことができます。

 rosay.server=> (use 'rosay.models)
 nil
 rosay.server=> (add-item (->Client "booyaka" "fark" "mailzer" "domain.com"))
 {:updated_on nil, :created_on #inst "2012-12-04T04:25:22.672462000-00:00", :email "mailzer",        :domain "domain.com", :password "fark", :username "booyaka", :id 10}

この問題に取り組む私の方法が正しいかどうか、または理にかなっているのかどうか、私はただ興味があると思います。これまでのところ、レコード タイプでプロトコルを呼び出すだけでクライアントとページの両方を実行でき、すべてが機能しているようです。おそらく私は問題を考えすぎており、いくつかの関数を書くだけで十分ですか?

ありがとう

4

1 に答える 1

2

IMO db のやり取りでのみ、2 つの離れたタイプの Client と Page の違いを隠すことはあまり役に立ちません。他のポリモーフィック操作 (オブジェクトの作成、オブジェクトの処理など) がなければ、コードを削減/抽象化することはできません。itemとにかく、これらのタイプは、すべてのアプリで「同じ」とは言えません。これらのタイプ (ページの追加、クライアントの追加など) に対して個別の操作を作成する方が明確です。これが本当に必要な場合は、ディスパッチメカニズムを提供するマルチメソッドを使用してソリューションとソリューションを比較できますが、OOP の使用を強制する必要はありません。

于 2012-12-04T05:22:59.147 に答える