CLojure:高阶函数与协议与多方法相比

时间:2014-10-25 15:08:06

标签: clojure protocols abstraction higher-order-functions multimethod

有很多协议与多方法比较,但为什么不使用更高阶函数? 让我们举个例子: 我们有一些数据(例如记录)。我们有方法序列化反序列化。 假设我们要将其保存到文件,json和数据库中。 我们应该创建名为 SerializationMethod 的协议以及实现它们的名为数据库 json 文件的记录吗?看起来只是为了使用协议来创建记录。第二种解决方案 - 多方法 - 可以采用字符串参数和序列化输出,并决定如何执行此操作。但我不确定这是正确的方法...... 第三种方法是编写函数序列化然后传递数据和序列化函数。但是现在我不能命名具有相同名称的序列化和反序列化方法(例如json):

(defn serialize [method data]
  (method data))

(defn json[data]
  (...))

问题是我怎么能(或我该怎么做)这样做。有更高阶函数的通用方法吗?或者我可能不太了解某事? 这是我对clojure的第一步,所以请宽容。

1 个答案:

答案 0 :(得分:2)

转换为JSON不同于写入数据库或文件,因为后者是IO操作,第一个是纯数据转换。考虑到这一点,我不建议在同一界面下实现它们。

现在假设你有各种序列化实现,比如说json和fressian,在你想要(de - /)序列化的每个数据结构上实现它们肯定不是一个好主意。你观察到这将是一个黑客是正确的。更简洁地说,它将限制记录仅通过一个实现(de / /)序列化。

相反,拥有不同的Serializer会更有效,每个Serializer都实现相同的接口:

(defrecord JSONSerializer []
  SerializationMethod
  (serialize [this data] ...)
  (deserialize [this data] ...))

(defrecord FressianSerializer []
  SerializationMethod
  ...)

这样我们最终会有几个序列化器对象可以传递给需要一个的函数。这些功能并不需要关注实施。

是否可以传递更高阶的函数?

(defn do-something 
  [params serialize deserialize]
  ...)

它也会起作用。但请注意,这种风格很快就会失控。 E. g。考虑应该编写一个函数的场景,该函数从一种格式反序列化数据并将其序列化到另一种格式。