CLojure:高阶函数 vs 协议(protocol) vs 多方法

标签 clojure protocols abstraction higher-order-functions multimethod

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

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

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

问题是我如何(或我应该如何)做到这一点。是否有更通用的高阶函数方法?或者也许我不太明白? 这是我接触 Clojure 的第一步,所以请多多包涵。

最佳答案

转换为 JSON 不同于写入数据库或文件,因为后者是 IO 操作,前者是纯粹的数据转换。考虑到这一点,我不建议在同一接口(interface)下实现它们。

现在假设您有各种序列化实现,比方说 json 和 fressian,在您想要(反/)序列化的每个数据结构上实现它们肯定不是一个好主意。您认为那将是黑客攻击的观点是正确的。更简明地说,它将限制记录只能通过一种实现进行(反/)序列化。

相反,拥有不同的序列化器会更有效,每个序列化器都实现相同的接口(interface):

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

(defrecord FressianSerializer []
  SerializationMethod
  ...)

这样我们最终得到了几个序列化器对象,这些对象可以传递给需要一个的函数。这些函数不需要关心实现。

是否可以传递高阶函数?

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

它也会起作用。但是请注意,这种风格很快就会失控。例如考虑这样一个场景,其中应该编写一个函数来反序列化一种格式的数据并将其序列化为另一种格式。

关于CLojure:高阶函数 vs 协议(protocol) vs 多方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26563832/

相关文章:

ios - 具有父类(super class)和子类的 Swift 协议(protocol)扩展方法分派(dispatch)

ios - Netty Channel 关闭检测

ios - 在 Swift 中从选择器调用协议(protocol)函数

.NET 反射/HTML 抽象?

python - 一种在简单界面后转换和组合多种数据类型的模式

string - Clojure 字符串映射

loops - 无限循环重现

clojure - 要在Prismatic/Schema中打开/关闭验证的全局标志?

c++ - 使用数组时的抽象与性能

clojure - 有反向映射功能吗?