在clojure中依赖于环境的协议/多方法的派遣

时间:2012-04-23 15:40:17

标签: architecture clojure

我在如何构建我的软件的某个特定部分时遇到了问题。 可以说,我有一个名为make-temp-dir(和许多其他人)的功能 一些黑魔法取决于当前的操作系统。我希望能够把 在单独的命名空间中为每个操作系统实现这些方法。

首先,我认为协议(如果可能)或多方法是解决方案 这个。但是,我从未见过将这些用于实现的示例 跨越多个名称空间。我无法弄清楚它是如何工作的 进行。

其次,如果我使用协议,我将不得不调用这些方法 像

(make-temp-dir current-os arg-1 arg-2)

不知何故,将os作为第一个参数始终传递并不太好 对我来说。出于语义原因,我希望make-temp-dir采取智能 决定取决于操作系统。当然我可以使用一些宏并执行类似

的操作
(doto current-os
  (make-temp-dir arg-1 arg2))

但这感觉不对。

应该怎么做?或者我走错了路?任何帮助表示赞赏。

编辑:好的,非常感谢@kotarak,我设法让事情变得有效。对于任何偶然发现此事的人,https://gist.github.com/2477120。工作正常,我想我会顺其自然。谢谢大家。

2 个答案:

答案 0 :(得分:7)

(ns your.utils)

(def current-os)

(defmulti make-temp-dir
  (fn [& _] current-os))

(ns your.utils.mac)

(defmethod make-temp-dir :mac-os-x
  [a b]
  (...))

(ns your.utils.win)

(defmethod make-temp-dir :windows
  [a b]
  (...))

在您的启动代码中,您必须先使用current-os初始化alter-var-root,然后才能使用任何实用程序功能。

(let [os (find-os)]
  (alter-var-root #'current-os (constantly os))
  (require (case os
             :mac-os-x 'your.utils.mac
             :windows  'your.utils.win)))

希望能让你开始。

答案 1 :(得分:1)

我不能肯定地说,但听起来你最终可能会重新发明Java为你提供的轮子。试试https://github.com/Raynes/fs以获得除了clojure.java.io(http://clojuredocs.org/clojure_core/clojure.java.io)中基本工具之外的Java提供的一些方便的包装。

如果您的问题超出特定于操作系统的分支到特定于环境的配置值,您可能会发现https://github.com/drakerlabs/milieu非常有用。我在Draker的这个专有项目中编写了这段代码,我们最近刚刚将它作为免费软件发布。我们还没有正式向社区宣布它,但它在Clojars中并且可以使用。反馈表示赞赏!驱动其创建的概念是dev / test / staging / production等意义上的环境,但我认为没有理由不能将它用于为不同的OS环境配置变量。