Clojure:多方法与协议

时间:2012-05-22 22:17:45

标签: clojure

上下文

我最近写了很多涉及多方法和协议的代码。

我发现我的大多数方法都是单一调度 - 它们只取决于其中一个参数的类型。

这些情况下,实际上可以通过向协议添加额外字段来替换多方法。

问题

在可以用协议替换多方法的情况下,是否有任何理由使用多方法代替协议?

谢谢!

3 个答案:

答案 0 :(得分:2)

如果您的要求有可能发生变化,并且将来需要利用多次发送,您可以选择使用多方法。

否则,您应该在协议满足您的目的时使用协议。

答案 1 :(得分:2)

我通常更喜欢协议:它们提供更好的性能并且能够很好地处理常见情况(单一调度类型)。

有时你真的需要更复杂的调度,在这种情况下你可以:

  • 全力以赴并使用多方法
  • 编写一小段自定义代码(通常为(cond .....))来处理调度。有时这比多方法更好,因为例如multimethods不能很好地处理数值范围。

一个有用的额外建议是以委派给适当协议功能的方式编写主(公开)函数。

e.g。它可能是这样的:

(defn my-api-function [a b]
  "Do interesting things with a and b"
  (multimethod-function
    (protocol-function a)
    (protocol-function b)))

这为您提供了足够的灵活性,可以在以后更改内部实现,而无需进行大量重构或影响调用代码。

答案 2 :(得分:2)

就个人而言,我更喜欢多方法,因为它们比协议更有效地将表示与行为分离开来。除了性能之外,我认为没有理由牺牲使用普通地图来表示我的数据,根据需要添加多个调度,或者分配“物理”类型以外的属性的选项(这本身通常不是一个很好的概念)在我看来依赖。