【问题标题】:which clojure library interface design is best?哪个clojure库界面设计最好?
【发布时间】:2009-09-03 03:03:59
【问题描述】:

我想提供消息读取器/写入器的多种实现。最好的方法是什么?

这是我目前正在考虑的一些伪代码:

  • 只需要所有实现都必须提供的一组函数,并将其留给调用者来保持正确的流

    (ns x-format)
    (read-message [stream] ...)
    (write-message [stream message] ...)
    
  • 返回一个包含两个封闭函数的映射

    (ns x-format)
    (defn make-formatter [socket]
      {:read (fn [] (.read (.getInputStream socket))))
       :write (fn [message] (.write (.getOutputStream socket) message)))})
    
  • 还有别的吗?

【问题讨论】:

    标签: lisp clojure


    【解决方案1】:

    我认为第一个选项更好。它更具可扩展性,具体取决于这些对象的使用方式。如果函数和对象是分开的,则添加或更改适用于现有对象的新函数会更容易。在 Clojure 中,通常没有太多理由将函数与它们所处理的对象捆绑在一起,除非您真的想对代码的用户隐藏实现细节。

    如果你正在编写一个你期望有很多实现的接口,也可以考虑使用multimethods。您可以让默认抛出“未实现”异常,以强制实现者实现您的接口。

    正如Gutzofter 所说,如果您考虑第二个选项的唯一原因是让人们不必在每次函数调用时都输入参数,您可以考虑让所有函数都使用一些 var 作为默认值socket 对象并编写一个with-socket 宏,它使用binding 来设置该变量的值。请参阅默认使用*out* 的值作为输出流的内置打印方法,以及将*out* 绑定到字符串写入器的with-out-str,作为Clojure 示例。

    This article 你可能会感兴趣;它将一些 OOP 惯用语与 Clojure 等价物进行比较和对比。

    【讨论】:

      【解决方案2】:

      我认为 read-message 和 write-message 是实用函数。您需要做的是将您的函数封装在一个 with- 宏中。请参阅 common lisp 中的“with-output-to-string”以了解我的意思。

      编辑: 当您使用 with- 宏时,您可以在宏扩展中进行错误处理和资源分配。

      【讨论】:

        【解决方案3】:

        我会选择第一个选项并将所有这些函数设为多方法。

        【讨论】:

          猜你喜欢
          • 2011-06-07
          • 2013-10-07
          • 2018-06-11
          • 2013-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-12
          相关资源
          最近更新 更多