2

Clojure 関数の一部を「浄化」しようとしています。すべての副作用コードが 1 つの関数で明示的に宣言されるようにしたいと考えています。最初にデータを取得し、最後にそれを db に書き込み、その間に純粋な関数を変換するのは簡単です。ただし、通常の状況では、変換関数はロジックの途中で別の DB 読み取りを必要とします。

(defn transform-users
      [users]
      (let [ids (map :id users)
            profiles (db/read :profiles ids)]
       (profiles->something profiles)))

(->> (db/read :users)
     (transform-users)
     (db/write :something)

明らかにこれは非常に単純な例ですが、要点は、db/readそこから副作用のある関数を取得するにはどうすればよいか、どうすればtransform-users純粋にすることができるか (そして利点として、簡単にテストできるようにするか) です。

4

2 に答える 2

1

ここでできることの 1 つは、(潜在的に) 副作用のある関数をオプションのパラメーターとして提供する依存性注入のようなアプローチです。

(defn transform-users
  [users & {:keys [ids->profiles]
            :or {ids->profiles #(db/read :profiles %)}]
  (let [ids (map :id users)
        profiles (ids->profiles ids)]
    (profiles->something profiles)))

多くの労力をかけずに注入された関数をモックできるため、これは簡単にテストできるはずです。おまけとして、デフォルト値を指定することで、期待していることを文書化し、関数を呼び出すのに便利になります。

于 2014-11-19T17:20:13.593 に答える
1

プロファイルの読み取りとプロファイルの変換を組み合わせるのはなぜですか?

  (->> (db/read :users)
       (map :id)
       (db/read :profiles)
       (profile->something)
       (db/write :something)

(これは、データベースへの 2 回の往復を行っているという事実も明らかにします。どこ db/read :user-profiles ですか?)

  (->> (db/read :user-profiles)
       (profile->something)
       (db/write :something)

多分:

  (->> (read-profiles-from-users)
       (profile->something)
       (db/write :something)
于 2014-11-19T22:57:55.647 に答える