如何处理一个库中的变量需要在它外面设置? [英] How to deal with a variable in a library that needs to be set outside of it?

查看:143
本文介绍了如何处理一个库中的变量需要在它外面设置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在几个项目中使用Datomic,现在是时候把所有的公共代码移动到一个小的实用程序库。



一个挑战是处理大多数操作所依赖的共享数据库 uri ,但必须设置该项目使用库。我想知道是否有一个完善的方法来做到这一点。以下是我想到的一些替代方案:




  • 删除 uri


  • 通过 alter-var->变量修改

    root $ / $>
  • 在动态库中保存它 * uri * 并覆盖希望的小适配器层中的值,如



    (def my-url ... bla ...) / p>

    (defn my-fun [args]
    (with-datomic-uri my-uri
    my-fun args))


  • uri / li>


解决方案

Stuart Sierra最后一个演示文稿是Clojure / West,名为 Clojure in the Large ,处理较大的Clojure应用程序的设计模式<



其中一个是你描述的问题。



总结关于手头的问题的提示:



1清除构造函数



所以你有一个明确的初始状态。

 (defn make-connection [uri] 
{:uri uri
...}

2使依赖关系清楚

  update-db [connection] 
...

>

 (deftest t-update 
(let [conn(make-connection)]
。(update-db conn)))))

4更安全重载

 (require ...:reload)

在要在以后绑定的变量中保留 uri 是很常见的,但引入了隐藏的依赖关系,也假设 body 一个单线程。



观看演讲,更多设计提示。


I'm using Datomic in several projects and it's time to move all the common code to a small utilities library.

One challenge is to deal with a shared database uri, on which most operations depend, but must be set by the project using the library. I wonder if there is a well-established way to do this. Here are some alternatives I've thought about:

  • Dropping the uri symbol in the library and adding the uri as an argument to every function that accesses the database

  • Altering it via alter-var-root, or similar mechanism, in an init function

  • Keeping it in the library as a dynamic var *uri* and overriding the value in a hopefully small adapter layer like

    (def my-url ...bla...)

    (defn my-fun [args] (with-datomic-uri my-uri (apply library/my-fun args))

  • Keeping uri as an atom in the library

解决方案

There was a presentation from Stuart Sierra last Clojure/West, called Clojure in the Large, dealing with design patterns for larger Clojure applications.

One of those was the problem you describe.

To summarize tips regarding the problem at hand:

1 Clear constructor

So you have a well defined initial state.

  (defn make-connection [uri]
      {:uri uri
       ...}

2 Make dependencies clear

  (defn update-db [connection] 
     ...

3 It's easier to test

(deftest t-update
  (let [conn (make-connection)]
    (is (= ... (update-db conn)))))

4 Safer to reload

 (require ... :reload)

Keeping uri in a variable to be bound later is pretty common, but introduces hidden dependencies, also assumes body starts and ends on a single thread.

Watch the talk, many more tips on design.

这篇关于如何处理一个库中的变量需要在它外面设置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆