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-nameと正しいコレクション文字列が返されますが、それらを呼び出すと。が発生します。Clojureを使用して、この些細なOO型の目標をどのように達成できますか?UserNewsItemsaveAbstractMethodError

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 に答える