11

在 Clojure 中,我想要一个协议,其中一些方法具有默认实现,而另一些则具有自定义实现。第一个参考后一个进行配置。这是一个例子:

(defprotocol Saving
  (save [this] "saves to mongodb")
  (collection-name [this] "must return a string representing the associated MongoDB collection"))

;Default implementation

(extend-type Object
  Saving
  ; the `save` method is common for all, so it is actually implemened here
  (save [this] (mc/insert (collection-name [this]) this))
  ; this method is custom to every other type
  (collection-name [this] "no_collection"))

;Particular implementations

(defrecord User
  [login password]
  Saving
  (collection-name [this] "users"))

(defrecord NewsItem
  [text date]
  Saving
  (collection-name [this] "news_items"))

但是,它不会以这种方式工作。即使调用collection-nameorUser实例NewsItem返回正确的集合字符串,调用save它们也会导致AbstractMethodError. 如何使用 Clojure 实现这个微不足道的 OO 形目标?

4

1 回答 1

14

使保存功能成为正常功能:

(defn save [obj] (mc/insert (collection-name obj) obj))

该协议应该只有collection-name

(defprotocol Saving
  (collection-name [this] "must return a string representing the associated MongoDB collection"))

然后每个想要“保存”的对象都可以实现这个协议。

记住:OO 风格经常隐藏明显的简单事物 :)

于 2013-02-23T11:56:53.387 回答