Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正在使用clojure';s stm作为一个全球国家被认为是一种良好做法?_Clojure - Fatal编程技术网

正在使用clojure';s stm作为一个全球国家被认为是一种良好做法?

正在使用clojure';s stm作为一个全球国家被认为是一种良好做法?,clojure,Clojure,在我的大多数clojure程序中。。。我看到很多其他clojure程序,原子中有某种全局变量: (def *program-state* (atom {:name "Program" :var1 1 :var2 "Another value"})) 在法典中偶尔会提到这种状态 (defn program-name [] (:name @*program-state*)) 阅读这篇文章让我重新思考全局状态,但不知何故,尽管我完全同意

在我的大多数clojure程序中。。。我看到很多其他clojure程序,原子中有某种全局变量:

(def *program-state* 
   (atom {:name  "Program"
          :var1  1
          :var2  "Another value"}))
在法典中偶尔会提到这种状态

(defn program-name []
    (:name @*program-state*))
阅读这篇文章让我重新思考全局状态,但不知何故,尽管我完全同意这篇文章,但我认为在atoms中使用哈希映射是可以的,因为它提供了一个通用的接口来操作全局状态数据(类似于使用不同的数据库来存储数据)


我想对这个问题有一些其他的想法。

我认为拥有一个偶尔以交换方式更新的单一全局状态是很好的。当您开始有两个需要更新的全局状态,线程开始使用它们进行通信时,我开始担心了

  • 保持当前全局用户的计数是可以的:
    • 任何线程都可以在任何时候加入或删除该线程,而不会伤害其他线程
    • 如果它从你的线下变出来,什么也不会爆炸
  • 维护日志目录有问题:
    • 当它更改时,所有线程是否都会停止向旧线程写入
    • 如果两条线发生变化,它们将会聚在一起
  • 将其用作消息队列更值得怀疑:

我认为拥有这样一个全局状态是很好的(在许多情况下是必需的),但我要小心的是,我的应用程序的核心逻辑具有将状态作为参数并返回更新状态的函数,而不是直接访问全局状态。基本上,我更喜欢从几组函数中控制对全局状态的访问,我的程序中的其他任何东西都应该使用这些方法来访问状态,因为这将允许我抽象出状态实现,即最初我可以从内存中的原子开始,然后可能会转移到一些持久性存储。

这种事情可以,但它通常也是一种设计气味,所以我会小心处理

需要考虑的事情:

  • 一致性-代码的一部分能否更改程序名?如果是这样,则从其他线程的角度来看,
    程序名
    函数的行为将不一致。不好
  • 可测试性-这容易测试吗?测试套件中更改程序名的一部分能否与读取程序名的另一个测试同时安全运行
  • 多个实例-应用程序的两个不同部分是否希望同时使用不同的程序名?如果是这样,这是一个强烈的暗示,您的可变状态不应该是全局的
可考虑的备选方案:

  • 使用ref而不是atom,至少可以确保事务中可变状态的一致性
  • 使用绑定可以将可变性限制在每个线程的基础上。这解决了大多数并发性问题,并且在全局变量像一组线程本地配置参数一样使用时会很有帮助
  • 尽可能使用不可变全局状态。它真的需要是可变的吗

谢谢!你对这篇文章有什么看法:@zcaudate:这篇文章是一篇典型的OO文章,关于“仅仅是另一种设计模式”。。。我建议。。不要这样做:)那么您将如何实现消息队列呢?我不完全确定我现在是否需要这个,但我相信在我当前的项目中,我迟早会遇到这样一种情况:我需要一个消息队列(即从一个IO线程按键到一个线程处理逻辑)对于多个实例的评论:)不计划需要两个全球国家会造成一些问题……不,这不是一个好的做法。像躲避瘟疫一样躲避它。如果必须这样做,那么尽量减少接触它或知道它的代码量。全局状态是模块化和可组合性的敌人。它耦合代码,使得重构或修复变得困难。如果你想通过repl与程序交互,你需要有一些全局状态。当然,你实际上不必告诉你的主程序该州是在全球范围内公开的,最好是像没有公开一样进行编程。