哪个clojure库界面设计最好?

时间:2009-09-03 03:04:00

标签: lisp clojure

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

以下是我正在考虑的一些伪代码:

  • 只需拥有一组所有实现必须提供的功能,并将其留给调用者以保持正确的流

    (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)))})
    
  • 别的什么?

3 个答案:

答案 0 :(得分:8)

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

如果您正在编写一个您希望实现许多实现的接口,请考虑使用multimethods。您可以让默认设置抛出“未实现”异常,以强制实现者实现您的接口。

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

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

答案 1 :(得分:3)

我认为读取消息和写入消息是实用程序功能。您需要做的是将函数封装在with-macro中。请参阅常见的lisp中的'with-output-to-string'以了解我的意思。

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

答案 2 :(得分:2)

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