2

私のclojureプログラムのほとんどで...そして私が見る他の多くのclojureプログラムでは、アトムにある種のグローバル変数があります:

(def *program-state* 
   (atom {:name  "Program"
          :var1  1
          :var2  "Another value"}))

そして、この状態はコードで時折参照されます。

(defn program-name []
    (:name @*program-state*))

この記事を読んでhttp://misko.hevery.com/2008/07/24/how-to-write-3v1l-untestable-code/グローバルな状態を考え直しましたが、どういうわけか、記事に完全に同意しているのに、グローバル状態データを操作するための共通のインターフェイスを提供するため、アトムでハッシュマップを使用しても問題ありません(データを格納するためにさまざまなデータベースを使用するのと同様です)。

この件について他に考えてみたいと思います。

4

3 に答える 3

2

こういうのは大丈夫ですが、デザイン臭も多いので気をつけてアプローチします。

考えるべきこと:

  • 一貫性-コードの一部でプログラム名を変更できますか?その場合、program-name関数は他のスレッドの観点から一貫性のない動作をします。良くない!
  • 妥当性-これはテストが簡単ですか?プログラム名を変更しているテストスイートの一部を、名前を読み取っている別のテストと同時に安全に実行できますか?
  • 複数のインスタンス-アプリケーションの2つの異なる部分で、同時に異なるプログラム名を使用することを期待することはありますか?もしそうなら、これはあなたの可変状態がグローバルであってはならないという強いヒントです。

考慮すべき代替案:

  • アトムの代わりにrefを使用すると、少なくともトランザクション内の可変状態の一貫性を確保できます。
  • バインディングを使用すると、可変性をスレッドごとに制限できます。これにより、ほとんどの同時実行の問題が解決され、グローバル変数がスレッドローカル構成パラメーターのセットのように使用されている場合に役立ちます。
  • 可能な限り不変のグローバル状態を使用します。本当に変更可能である必要がありますか?
于 2012-10-30T06:07:54.063 に答える
2

交換可能な方法で時折更新される単一のグローバル状態を持つことは問題ないと思います。更新が必要な 2 つのグローバル状態が発生し始め、スレッドがそれらを通信に使用し始めると、私は心配し始めます。

  • 現在のグローバル ユーザーの数を維持することは問題ありません。
    • どのスレッドも、別のスレッドを傷つけることなく、いつでもこれを inc または dec できます
    • スレッドの下から変更された場合、何も爆発しません。
  • ログディレクトリの維持には疑問があります:
    • 変更すると、すべてのスレッドが古いスレッドへの書き込みを停止しますか?
    • 2 つのスレッドが変更された場合、それらは収束します。
  • これをメッセージキューとして使用することは、さらに疑わしいです:
于 2012-10-29T23:16:15.293 に答える
1

このようなグローバルな状態を持つことは問題ないと思います (多くの場合、それが必要です) が、アプリケーションのコア ロジックに、状態をパラメーターとして受け取り、直接ではなく更新された状態を返す関数があることに注意してください。グローバル状態へのアクセス。基本的に、いくつかの関数セットからグローバル状態へのアクセスを制御することを好みます。プログラム内の他のすべてのメソッドは、これらのメソッドのセットを使用して状態にアクセスする必要があります。これにより、状態の実装を抽象化できます。つまり、最初に開始できます。インメモリアトムを使用すると、永続ストレージに移動できます。

于 2012-10-30T04:15:36.310 に答える