【问题标题】:How does Clojure approach Separation of Concerns?Clojure 如何处理关注点分离?
【发布时间】:2011-05-25 10:26:50
【问题描述】:

Clojure 如何处理关注点分离?由于代码是数据,所以函数可以作为参数传递并用作返回......

而且,因为有这样的原则“1000 个函数在 1 个数据结构上工作,比 100 个函数在 100 个数据结构上工作更好”(或类似的东西)。

我的意思是,把所有东西都打包成一个地图,给它一个关键字作为键,就是这样?函数、标量、集合,一切......

关注点分离的想法在 Java 中通过 Aspects(面向方面​​的编程)和注解来实现。这是我对这个概念的看法,可能有些局限,所以不要想当然。

在 Clojure 中什么是正确的方式(惯用方式),以避免其他程序员的 WTF _

【问题讨论】:

  • 您能否更具体地说明您的要求。关注点分离是一个用来表示 100 种不同事物的术语。
  • 方面是一种无需访问其源代码即可修改现有代码行为的方法。 Clojure 和其他 Lisps 通过动态变量提供了类似的东西,它们本质上是具有自己堆栈的全局变量。顶级函数(使用 defn 创建的)是动态变量,可以与binding 绑定。 binding 的语法看起来就像 let,但绑定是在绑定表单内的调用中使用的。

标签: clojure separation-of-concerns


【解决方案1】:

在函数式语言中,处理关注点分离的最佳方法是将任何编程问题转换为数据结构上的一组转换。例如,如果您编写一个 Web 应用程序,总体目标是获取请求并将其转换为响应,这可以被认为是简单地将请求数据转换为响应数据。 (在一个重要的网络应用程序中,起始数据可能不仅包括请求,还包括会话和数据库信息)大多数编程任务都可以这样考虑。

每个“关注点”都是“管道”中的一个函数,有助于实现转换。这样,每个功能都与其他步骤完全解耦。

请注意,这意味着您的数据在经历这些转换时需要具有丰富的结构。本质上,我们希望将程序的所有“智能”放入数据中,而不是代码中。在一个复杂的函数式程序中,不同级别的数据可能足够复杂,以至于需要看起来像一种编程语言本身——这就是“领域特定语言”的概念发挥作用的地方。

Clojure 为处理复杂的异构数据结构提供了出色的支持,这使得它不像听起来那么麻烦(即,如果操作正确,它一点也不麻烦)

此外,Clojure 对惰性数据结构的支持允许这些中间数据结构实际上(在概念上)无限大,这使得这种解耦在大多数情况下成为可能。请参阅以下论文,了解为什么在这种情况下拥有无限数据结构如此有价值:http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf

这种“管道”方法可以处理 90% 的分离关注点的需求。对于剩下的 10%,您可以使用 Clojure 宏,从高层次上讲,它可以被认为是面向方面编程的一个非常强大的工具。

这就是我认为你可以在 Clojure 中最好地解耦关注点的方式 - 请注意,在这种方法中,“对象”或“方面”并不是真正必要的概念。

【讨论】:

  • 说得好!另外请注意,如果您的大多数函数都是纯函数,您可以轻松地独立测试它们。
  • 所以,你得到的不是对象(在 OO 语言中),而是结构(在函数式语言中)。这是封装的相应“概念”(实现高凝聚力、低耦合、黑盒、模块化)?它有名字吗?
  • 一本关于类似管道方法的好读物(尽管在 Python 中):dabeaz.com/generators/Generators.pdf
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多