2011-04-06 36 views
14

如何實現Clojure中的面向方面編程?我們需要在Clojure中使用AOP嗎?
比方說,我們希望普通的香草Clojure的解決方案(沒有AspectJ的)。面向方面編程Clojure中

回答

13

AOP恕我直言,只是某些種類的靜態編程語言中的神器。 AFAIKS通常只是一堆非標準的編譯器擴展。我還沒有看到,不能在更多的動態語言可以更好地解決&本身AOP的任何應用程序。 Clojure肯定是充滿活力的,這甚至沒有考慮宏。

我可能是錯的,但即便如此,我需要看到的是不能在純Clojure的實現一樣好一個實際的AOP使用情況。

編輯:僅僅是明確的:我拒絕看東西喜歡的elisp的意見,面向方面。在動態語言,這些都只是技術在需要的時候,有沒有必要比的函數定義重新綁定其他語言支持使用 - 所有的Lisp支持反正。

沒有必要將它們視爲特殊 - 你可以很容易地在Clojure中定義自己的defadvice樣的功能。例如,見compojure's wrap! macro,這實際上是過時了,因爲你通常甚至不需要它。

+2

這是一種奇怪的說宏是動態的,因爲它們在編譯時運行(他們是掛鉤進入編譯器)。當您更改宏時,您需要重新編譯調用它的所有代碼。在我的書不是很活躍...... – Marek 2014-03-11 22:19:51

+2

此外,AOP是密切相關的締約方會議,Common Lisp的(也帕斯卡康斯坦薩是著名的倡導AOP爲CL)的元對象協議。你認爲Common Lisp也是靜態的嗎?這個答案似乎是(未)受過教育的猜測的隨機集合... – Marek 2014-03-11 22:22:53

+1

我認爲這個答案似乎暗示着(對於不熟悉Clojure的人),Clojure以某種方式消除了交叉擔憂而沒有任何額外的努力。關於這一點,mikera的答案更加清晰,並且還包括了一些例子,我認爲這應該是被接受的答案。事實上,這個答案和它的例子也突出了一些困難,這隻能進一步推論出Clojure沒有自動解決AOP/Cross-Cutting問題(通過任何其他名稱)的結論。 – Sprague 2014-10-01 10:57:42

11

面向方面的編程是實現分離 - 在Java中concernes的一個好方法。 Clojure的可組合抽象實現了這一點。另請參閱this question。該主題在Joy Of Clojure中涵蓋得非常好。

爲另一個名字面向Clojure的方式的一個例子檢查出的環網框架

20

面向方面編程通常用於交叉功能添加到,否則將業務邏輯得到絕望交織在一起的代碼。一個很好的例子就是日誌記錄 - 你不需要記錄分佈在代碼庫中任何地方的代碼。

你並不真正需要的AOP Clojure中,因爲它很容易與其他的Clojure技術來實現這一目標。

例如,你可以使用高階函數「包裝」等功能與跨領域的功能:

; a simple function - the "business logic" 
(defn my-calculation [a b] 
    (+ a b)) 

; higher order function that adds logging to any other function 
(defn wrap-with-logging [func] 
    (fn [& args] 
    (let [result (apply func args)] 
     (println "Log result: " result) 
     result))) 

; create a wrapped version of the original function with logging added 
(def my-logged-calculation (wrap-with-logging my-calculation)) 

(my-logged-calculation 7 9) 
=> Log result: 16 
=> 16 
+5

與AOP相比,該示例的問題是現在開發人員必須調用新的包裝方法,而不是原來的包裝方法。理想情況下,可以通過調用原始方法來實現日誌記錄行爲。這將更接近AOP提供的,對嗎? – jcrossley3 2011-04-07 17:59:19

+7

@ jcrossley3 - 如果你想要,你總是可以重新定義原始函數(def my-calculation(wrap-with-logging my-calculation))。 – mikera 2011-04-07 19:40:08

+0

優點! :) – jcrossley3 2011-04-10 17:02:10