gpt4 book ai didi

clojure - 如何删除 Compojure 应用程序中的全局数据

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

关于http://mindbat.com/2013/03/clojurewest-2013-day-one-notes/有一条注释写着:

  • 在顶层定义引用和原子基本上是通过单例的全局可变状态,请避免
  • 建议使用构造函数返回您要使用的状态变量,然后将该状态传递给每个函数

我认为这是一个很好的建议,但我不完全确定如何在 Ring/Compojure 应用程序中实现它。谁能举一个具体的例子来说明这是如何工作的?

我特别感兴趣的是如何以这种方式将 defroutesinitapp 组合在一起并摆脱该范围内的全局变量。

最佳答案

我从斯图尔特的演讲中了解到的是这样的:

(ns state.core)

(defn create-user-module [] (atom []))

(defn add-user [module user]
(swap! module conj user))

(defn get-users [module]
@module)

现在,您的“核心”中没有全局状态,因为操作状态的函数期望将其作为参数获取。这些允许轻松测试,因为您可以为每个测试创建“用户模块”的新实例。此外,该模块的客户端不应该关心他们在 create-user-module 函数中获得的内容,他们应该只是将其传递而不检查它,这样您就可以随时更改用户模块实现。如果您要拥有多个实现,Stuart 还讨论了为这些模块创建协议(protocol)。

试图回答你的问题,环形适配器只是 1 个参数的函数,而 compojure 只是一个路由库,因此你可以使用如下闭包创建一个网络应用程序:

(ns state.web
(:use compojure.core)
(:require [state.core :as core]))

(defn web-module [user-module]
(routes
(GET "/all" [] (core/get-users user-module))))

现在您可以调用 Web 模块来创建 Web 应用程序,并将所需的依赖项作为参数传递。当然,您仍然需要有人使用正确的用户模块创建 Web 应用程序,因此您只需要一个将所有内容连接在一起的“主”函数:

(ns state.main
(:require state.core
state.web)
(:use ring.adapter.jetty))

(defn start []
(let [user-module (state.core/create-user-module)
web-module (state.web/web-module user-module)]
(run-jetty web-module {:port 3000 :join? false})))

(defn stop [app]
(.stop app))

start 将从您的应用 main 方法中调用。这只是意味着您需要切换到 lein-run 插件。

现在,考虑到您正在询问 init (我假设来自 leinring 插件),我猜您计划在容器中部署您的 web 应用程序。由于 lein 环插件必须在 java servlet fw 约束内工作,并且处理程序最终编译为 java servlet,因此您可以做的最好的事情是:

(ns state.web
(:use compojure.core)
(:require [state.core :as core]))

(def module-deps (atom {})

(defn init-app [] (swap! module-deps conj [:user-module (core/create-user-module)]))

(defroutes web-module []
(GET "/all" [] (core/get-users (:user-module @module-deps))))

这仍然意味着你的核心命名空间很容易测试,但你仍然在 Web 命名空间中拥有全局状态,但我认为这是“正确”封装的,如果你必须使用 java 容器,这可能就足够了。

这只是为什么库比框架“更好”的另一个论据:)

关于clojure - 如何删除 Compojure 应用程序中的全局数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15600470/

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