19

我花了一些时间,试图了解 Clojure 多方法。据我所知,主要的“专业”多方法论点是它们的灵活性,但是,我对为什么多方法比简单的 if 或 case 语句更好的论点感到困惑。请有人解释一下,多态性和过分夸大的案例陈述之间的界限在哪里?

编辑:我应该在这个问题上更清楚,与“if”语句相比,我更感兴趣。非常感谢您的回答!

4

3 回答 3

29

假设我们有类型 A、B、C、D 和 E,方法 m1、m2、m3 采用先前类型的单个参数。您可以将它们放在这样的表中:

   | A | B | C | D | E |
m1 |   |   |   |   |   |
m2 |   |   |   |   |   |
m3 |   |   |   |   |   |

“switch”语句策略是一次执行该表的一行。假设您添加了一个新类型 F。您必须修改所有实现以支持它。

基于类的多态性(C++、Java 等)允许您改为实现一整列。因此添加新类型很容易,因为您不必更改已经定义的类。但是添加新方法很困难,因为您必须将它添加到所有其他类型。

多方法允许您独立地实现表格的单个单元格。

如果您必须调度多个参数,这种灵活性会更大。每个新参数都为该表添加了另一个维度,并且基于 swich 和基于类的调度都很快变得非常复杂(参见访问者模式)。

请注意,多方法实际上比描述的更通用,因为您可以调度几乎任何东西,而不仅仅是参数的类型。

于 2012-03-11T19:43:45.743 回答
20

多方法和大 if 语句的区别在于,您需要修改包含 case 语句的函数以将 case 添加到 if 语句中。您可以添加新方法而无需触及先前存在的方法。

因此,如果您在库中定义了一个多方法,并且您希望您的用户能够为他们自己的数据类型扩展它,那没问题。如果您改用 if 语句,那将是一个大问题。

于 2012-03-11T19:42:08.057 回答
2

可以通过查看这篇文章来扩展 ivant 上面的答案。它很好地解释了协议的力量。将多方法视为具有多个维度的协议。

于 2012-03-12T15:35:44.270 回答