2013-10-21 57 views
3

作爲clojure的新手,我努力尋找不同代碼構造的慣用風格。讓膨脹還是慣用clojure?

在某些情況下,我讓綁定包含大部分函數的代碼。這是膨脹,clojure哲學的一些誤解或慣用,並罰款?

這裏是一個示例測試用例來演示。它測試一些存儲庫的往返傳遞。長期讓人看起來更奇怪嗎?

(deftest garden-repo-add-get 
    (testing "Test garden repo add/get" 
    (let [repo (garden/get-garden-repo) 
      initial-garden-count (count (.list-gardens repo)) 
      new-garden (garden/create-garden "Keukenhof") 
      new-garden-id (.add-garden repo new-garden) 
      fetched-garden (.get-garden repo new-garden-id)] 
     (is (= (+ initial-garden-count 1) (count (.list-gardens repo)))) 
     (is (= (.name new-garden) (.name fetched-garden)))))) 
+1

可能我建議做盡可能多的4clojure練習越好,對實現檢查你的答案前十名其他用戶(和網站創建者)。我發現自己使用let作爲解決方案分解策略,但是其他答案顯示了其他您可能會喜歡的成語。它始終是內容豐富的。 –

回答

3

主要問題我看到您的let代碼,並且是通常的情況,您是否正在使用大量僅存在let form中的名稱的中間變量。

避免overbloat最好的方法是使用箭頭宏->->>

例如,您可以避開與

initial-garden-count (-> (garden/get-garden-repo) 
         (.list-gardens) 
         count) 

repo中間變量越少,你的具體情況,你」在你的測試驗證中重新使用全部你的中間變量,所以你無論如何都需要它們在let語句上。也許new-garden-id是唯一的中間,你可以迴避:

fetched-garden (->> (.add-garden repo new-garden) 
        (.get-garden repo)) 

或者使用Chiron公司提出的辦法:

fechted-gaden (.get-garden repo (.add-garden repo new-garden)) 
2

就個人而言,這就是我如何在Clojure中編寫代碼。 Clojure簡潔,優雅,簡潔。
我不認爲通過壓縮到以下將是「慣用」。

(is (= (+ (count (.list-gardens repo)) 1) (count (.list-gardens (garden/get-garden-repo))))) 

您的代碼片段更容易理解,以測試調試(在Eclipse中,IntelliJ ..)。

Clojure是關於簡單性,我想保持這種方式。

不過,您的問題的答案是非常有見地的。

+0

你的代碼錯過了返回項目的相等性測試,並且沒有測試添加花園合約(它返回一個可以用來查找項目的ID),它根本不等價。除了最初的花園計數之外,我沒有看到如何以一種自由形式重寫它。 – user499049

0

通過查看你的函數代碼,看起來函數正在處理的「東西」是具有getter/setter和方法的典型OO對象(請參閱有很多{something}調用),這使得您可以使用這些由於對象API的設計方式而允許綁定。如果你必須使用對象,這很好。

在Clojure中,你基本上圍繞像map/vector/list/set和functions這樣的數據結構來設計你的API,這在大多數情況下給你的API可能不需要那麼多的綁定使用。