Tôi đang cố gắng triển khai ý tưởng từ http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded vào cơ sở mã của tôi.Tránh trạng thái toàn cầu trong lớp DAO của ứng dụng Clojure
Tôi có một lớp dao, nơi tôi cần phải vượt qua trong cơ sở dữ liệu để tránh tình trạng toàn cầu. Có một điều khiến tôi phát điên là cụm từ:
Bất kỳ chức năng nào cần một trong các thành phần này đều phải lấy tham số . Đây không phải là gánh nặng như nó có vẻ: mỗi chức năng được, nhiều nhất, một đối số thêm cung cấp "bối cảnh" trong đó nó hoạt động. Ngữ cảnh đó có thể là toàn bộ đối tượng hệ thống, nhưng nhiều hơn thường sẽ là một số tập con. Với việc sử dụng khéo léo các đóng cửa từ vựng, các đối số thêm biến mất khỏi hầu hết các mã.
Tôi nên sử dụng bao đóng ở đâu để tránh chuyển trạng thái toàn cầu cho mọi cuộc gọi? Một ví dụ sẽ là để tạo ra một hàm init trong lớp dao, một cái gì đó như thế này:
(defprotocol Persistable
(collection-name [this]))
(def save nil)
(defn init [{:keys [db]}]
(alter-var-root #'save (fn [_] (fn [obj] (mc/insert-and-return db (collection-name obj) obj WriteConcern/SAFE)))))
Bằng cách này tôi có thể bắt đầu lớp dao của tôi từ hệ thống/khởi động chức năng như thế này:
(defn start
[{:keys [db] :as system}]
(let [d (-> db
(mc/connect)
(mc/get-db "my-test"))]
(dao/init d)
(assoc system :db d)))
này hoạt động, nhưng nó cảm thấy một chút icky. Có cách nào tốt hơn? Nếu có thể tôi muốn tránh buộc khách hàng của lớp dao của tôi phải vượt qua một cơ sở dữ liệu mỗi khi nó sử dụng một hàm.