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 仅在数据库交互中隐藏两种远程类型 Client 和 Page 之间的差异并不是很有用。如果没有其他多态操作(例如,对象创建、对象处理等),它不会减少/抽象代码。无论如何,这些类型太不同了,无法item在所有应用程序中“相同”。更清楚的是,只需为这些类型创建单独的操作(例如,添加页面、添加客户端)。如果您真的需要这个,您可以将您的解决方案与提供调度机制但不强迫您使用 OOP 的多方法的解决方案进行比较。

于 2012-12-04T05:22:59.147 回答