2013-10-23 44 views
2

我是clojure的新手,我試圖理解不同情況下可用的不同設計選擇。在這種特殊情況下,我想將緊密耦合的功能組合起來,並使得將這些功能作爲一個集合傳遞成爲可能。函數圖vs協議實現

  1. 何時使用函數映射將緊密相關的功能和何時使用協議(+實現)分組?

  2. 有什麼優點和缺點?

  3. 要麼更習慣?

作爲參考,這裏有兩個例子是我的意思。與Fn鍵地圖:

(defn do-this [x] ...) 
(defn do-that [] ...) 
(def some-do-context { :do-this (fn [x] (do-this x) 
         :do-that (fn [] (do-that) } 

,並在第二種情況下,

(defprotocol SomeDoContext 
    (do-this[this x] "does this") 
    (do-that[this] "does that") 

(deftype ParticularDoContext [] 
    SomeDoContext 
    (do-this[this x] (do-this x)) 
    (do-that[this] (do-that)) 

回答

1

這一切都取決於你的意思是「緊密相關的功能」。可以有2種解釋:

  • 這些組函數實現該系統的特定組件/子系統。例如:日誌記錄,身份驗證等。在這種情況下,您可能會使用clojure名稱空間(AKA模塊)對相關函數進行分組,而不是使用散列映射。

  • 這些函數集合在一些數據結構或類型或對象等上一起工作。在這種情況下,您將使用基於協議的方法,它允許ad-hoc多態性,以便新類型也可以提供這組功能。例如:任何接口之類的話:可排序,打印等

+0

那麼應該何時使用功能圖呢? – 4ZM

+0

我個人,不會使用功能的地圖,只使用地圖的數據 – Ankur

0

我的第一印象將是第一種方式是面向數據和第二種方式是類型爲主。到目前爲止,我更喜歡面向數據。 也許這個決定與Alan Perlis的報價有關:「最好在一個數據結構上運行100個函數,而不是在10個數據結構上運行10個函數。」

+1

呀。我已閱讀Rich Hickey關於「[關於識別和使用地圖的重要性](https://groups.google.com/forum/#!topic/clojure/4II-HKr_Pu0)」的評論「。這使我對類型的愛好,以界面爲中心的OO思維受到一點傷害;但也許它只是一個階段;) – 4ZM

1

協議是像Interfaces所以如果你想創建的是一個,使用的協議。

如果你只是試圖組related functions某處使用namespace,沒有什麼特別的Object浮動功能可以。

在我看來,你正在考慮對象,並使用map只是模擬一個對象或一個結構,你將你的功能連接在一起。除非它確實是一種類型或協議,並且在這些情況下您應該使用defrecorddeftypedefprotocol,這會給我帶來不自然的感覺。

一個實例採取from here有關使用defprotocoldefrecord

(defprotocol IAnimal 
    "the animal protocol" 
    (inner-report [o] "a report")) 

(defrecord Dog [] 
    IAnimal 
    (inner-report [o] 
    (println "Woof Woof.\n"))) 

(defrecord Cat [] 
    IAnimal 
    (inner-report [o] 
    (println "Meow Meow.\n")))