2011-04-06 75 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