首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用闭包的数据封装

使用闭包的数据封装
EN

Stack Overflow用户
提问于 2013-03-22 14:53:51
回答 2查看 171关注 0票数 3

我想知道在Clojure中实现数据封装的惯用方法是什么。下面,我描述了我的特定用例,以激发我提供的示例代码。

我在dbaccess模块中有代码,它执行一个复杂的数据库查询,从数据库中获取一些数据。我还有一些函数对返回的原始数据进行操作。然后,这些函数提供了对数据的更处理、更精细的视图,并使用来自系统中其他模块的不同参数多次调用。让我们称它们为"API函数“。

查询很重,应该在开始时只执行一次,然后API函数将对内存中的原始数据进行操作,而不必执行另一个DB查询。

下面是我使用闭包的方法:

dbaccess模块

代码语言:javascript
复制
(ns dbaccess)
    (let
        [raw-data (complex-database-query)]
      (defn create-client-names []
        (fn [some-args] raw-data))
      (defn create-client-portfolio []
        (fn [some-args] raw-data))
      (defn create-client-stocks []
        (fn [some-args] raw-data)))

其他客户端模块

代码语言:javascript
复制
(def client-names (create-client-names))

(doall (map println (client-names "Baltimore")))

我不喜欢为捕获原始数据的创建函数命名。

更重要的是,上面的代码不允许客户端模块在查询执行之前配置查询的各个方面(例如数据库连接信息)。

另一方面,如果不使用闭包,我必须在dbaccess模块和其他需要调用API函数的模块之间显式地传递原始数据。有更好的办法吗?我是否应该在dbaccess模块中使用可变状态?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-22 16:05:25

我必须在dbaccess模块和其他需要调用API函数的模块之间显式地传递原始数据。

应该这样做,显式地传递函数所需的数据,因为:

  • 这将导致数据创建方式和处理方式之间的松散耦合。
  • 功能将更清楚地理解,同时阅读它。
  • 测试单个函数很容易,因为您可以轻松地模拟数据。
票数 3
EN

Stack Overflow用户

发布于 2013-03-22 19:12:25

我想在这种情况下你不需要let

代码语言:javascript
复制
(def ^:private raw-data (promise))

(future (deliver raw-date (complex-database-query))) ;; A. Webb mentioned this

(defn create-client-names []
  (fn [some-args] @raw-data))

...

为什么create-client-names和其他函数不只是

代码语言:javascript
复制
(defn create-client-names [some-args]
  @raw-data)

...

如果有祈使体,海事组织最好使用doseq而不是map

代码语言:javascript
复制
(doseq [name (client-names "Baltimore")]
  (println name))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15573378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档