gpt4 book ai didi

clojure - clojure 中的存储库模式

转载 作者:行者123 更新时间:2023-12-01 02:22:12 25 4
gpt4 key购买 nike

作为 clojure 的新手,我想要一些关于实现存储库模式的建议*。

在 OO 语言中,我会创建一个存储库接口(interface)、一个测试和至少一个 db impl。我会在引导期间实例化它们,使用 DI 传递对象或通过服务定位器获取它们。我猜它在clojure中完全不同?

1)什么是对 repo 中的功能进行分组的好方法?协议(protocol),命名空间中的“免费”功能?

2) 我在哪里实例化存储库后端,即分配资源,如 db-connections 等?我是实例化存储库协议(protocol)的实现并将其分配给原子,还是在自由函数的情况下重新定义它们?

*) 存储库是持久性的后端抽象,通常支持 CRUD 风格的操作范围。

编辑:这是我目前使用的方法。对功能进行分组的协议(protocol)。一个测试和一个实现它的“真实”记录。然后是一个原子来注册 repo 。

(defprotocol GardenRepo
"Repository of Gardens. Supports CRUD style operations."
(list-gardens [repo] "Get a seq of all gardens in the repo.")
(get-garden [repo id] "Get a specific garden by it's id.")
...)

(let [repo (atom nil)]
(defn get-garden-repo [] @locator)
(defn set-garden-repo [new-repo] (reset! repo new-repo)))

最佳答案

1)通过共享子问题对功能进行分组。在我们的 ORM 中,我们有一个用于 db 交互的命名空间,一个用于每个目标 db 的单独命名空间,一个用于模型构建和查询操作的命名空间,一个用于字段定义的命名空间,一个描述字段协议(protocol)的每个实现的单独命名空间(即 int、string , 文本, 蛞蝓, 集合)。

2)使用返回所有使用的函数的函数,每个函数都隐式使用传入配置定义的资源,即:

(defn make-repository
[config]
(let [db (initialize-db config)
cleanup #(do-cleanup db)
store (fn [key val] (store-data key val db))
retrieve (fn [key] (retrieve-data key db))]
{:db db ;; this is optional, can be very useful during initial development
:cleanup cleanup
:store store
:retrieve retrieve}))

如果功能的访问是性能瓶颈,这当然可以创建记录的实例,并且如果您想定义相同功能的多个实现(可能需要不同设置的不同数据库驱动程序等),记录可以实现协议(protocol).库的用户根据他们自己的设计决定如何以及在何处绑定(bind)您返回的这些函数。

客户端如何使用此存储库的示例:
(def repo (make-repository config))

(def cleanup-repo (:cleanup repo))

(def store-to-repo (:store repo))

(def retrieve-from-repo (:retrieve repo))

(defn store-item
[data]
(let [processed (process data)
key (generate-key data)]
(try (store-to-repo key data)
(catch Exception e
(cleanup-repo)))))

关于clojure - clojure 中的存储库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19489029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com