如何在Clojure中实现面向方面的编程?我们在Clojure是否需要AOP?假设我们想要普通的香草Clojure解决方案(无AspectJ)。
AOP IMHO只是某些静态编程语言的产物。 AI通常只是一堆非标准的编译器扩展。我还没有看到任何AOP的应用程序无法用更多动态语言更好地解决本机问题。 Clojure当然是足够动态的,并且甚至不需要考虑宏。
我可能是错的,但如果是这样,我需要查看一个实际的AOP用例,该用例无法在纯Clojure中同样实现。
编辑:只是为了清楚:我拒绝将elisp的建议视为面向方面。在动态语言中,这些只是您需要时可以使用的技术,除了重新绑定函数定义(所有lisps仍然支持)之外,不需要语言支持。
无需将它们视为特殊对象-您可以在clojure中轻松定义自己的类似defadvice的函数。例如,请参阅compojure's wrap! macro,实际上它已被弃用,因为您通常甚至不需要它。
面向方面的编程通常用于向代码添加跨领域功能,否则这些代码将不可避免地与业务逻辑交织在一起。一个很好的例子是日志记录-您实际上并不希望记录代码分散在代码库中的各处。
在Clojure中您实际上并不需要AOP,因为使用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
面向方面的编程是在Java中实现关注点分离的好方法。 Clojure的可组合抽象很好地实现了这一点。另请参见this question。 [Joy Of Clojure]很好地涵盖了该主题。
作为另一个以Aspect Oriented Clojure为例的示例,请查看Ring Web框架
嗯,您可以轻松获得带有Clojure的AOP。只需在函数中使用元数据来通知您何时需要日志: