В 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-name
в экземпляре User
или NewsItem
возвращает правильную строку коллекции, вызов save
на них вызывает AbstractMethodError
. Как я могу достичь этой тривиальной цели с OO-формой с помощью Clojure?