6

作为一名 Ruby on Rails 开发人员,在设计/实现 Web 应用程序时,我从问题域中获取基本概念/实体并将它们作为模型来实现。通常,这些是从基本 ORM 类(例如ActiveRecord::Base)派生的类,它们映射数据库表中的记录并添加包含实现与模型相关的业务逻辑的额外方法。

这种方法的优点是可以快速从问题域中找到与对象相关的所有业务逻辑,这样在模型类不大的情况下可以有效地理解应用程序的那部分工作原理。它还与所有表示逻辑分开。此外,由于 ORM,业务逻辑方法包含很少的特定于 DB 的代码,因此非常干净且易于阅读。

缺点是这样的类通常会增长到巨大的规模,因此很难作为一个整体来理解。

所以我的问题是:

  • Clojure 生态系统是否提供了一些库来实现与 OOP 的 ORM 类似的功能?
  • 组织此类代码的“Clojure 方式”是什么?
  • 该方法的优点和缺点是什么?
  • 一些文章/书籍/演讲可以解释和证明该方法的合理性?
  • 是否有一些展示该方法的开源(示例)应用程序?
4

2 回答 2

8

One of the driving philosophies behind the development of Clojure is to separate complex things to the greatest degree that is reasonable, and to treat data as data and hence to avoid combining data and separate value state and identity.

  • Do Clojure ecosystem provide some libraries that fulfil a similar function as OOP's ORMs? The desire to process data with pure functions that transform one data structure into another causes some clojure programmers to shy away from ORMs though there is no reason you can't use Hibernate in Clojure if you really want to.

  • What is the "Clojure way" to organize such code? I like Amit Rathore's presentation of the topic

  • What are the advantages and disadvantages of the approach? Rich Hickey gives an excellent discussion of these ideas in this classic video
  • Some articles / books / talks that explain and justify the approach? I personally recommend The Joy of Clojure,
于 2013-10-03T21:03:12.627 回答
8

简而言之,您不会将东西包装在对象中,而是直接使用列表、集合和映射等数据结构进行编程。因此,ORM 所做的工作被简化为将一种数据结构转换为另一种数据结构:例如,一个user-row->user-record函数可能会将您从 SQL 数据库弹出的值列表转换为表示应用程序业务逻辑中的用户的映射。保存用户时,您必须调用反向函数。

我不得不说,对于一个有经验的 OOP 程序员来说,很难“理解”这样一个事实,即围绕事物的仪式要少得多。我们的大脑似乎反对这个想法 - 恕我直言,因为对于经验丰富的开发人员/软件架构师来说,它似乎过于简单和不成熟。:-) 我希望我能写出更复杂的回复,里面满是奇怪的术语,听起来像个真正的专家,但实际上我做不到,因为没有太多要补充的了。:-)

顺便说一句,一个小而有趣的观点 - 数据结构的普遍使用是一种在 OOP 世界中被认为是错误的做法。例如,您不应该将钱存储在一个简单的元组中[10, "USD"],而应该编写完整public class Money的封装所有货币、比较、舍入等。但是编写元组正是我们在 FP 中所做的。我记得我对这来自 OOP 世界有一些奇怪的感觉。

在组织代码时,与 OOP 中的规则或多或少在命名空间方面适用。您可以像在 java 包中一样根据主题组织代码,除了所有函数(您用来调用方法的函数)现在都是无状态的,并且通常将上述用户记录之类的内容作为参数。因此,foo.barChange()您将拥有(bar foo)where 纯函数bar将返回一个新的数据结构foo2而不是修改foo.

话虽这么说,OOP 的好处之一是,不仅有许多应用程序使用这种范式编写,更重要的是,已经尝试了多方法(这就是我们如何得到今天流行的 DI 容器等的方法) ...)。函数式编程还没有这个。基本上没有人有关于如何在 FP 中构建应用程序架构的经过验证的最终手册。顺便说一句,这就是为什么人们通常不鼓励编写大型框架并鼓励他们继续使用数据转换功能。这样,您始终可以按照您想要的方式连接它并避免架构陷阱。

于 2013-10-04T14:17:56.340 回答