Rails 类型的 webapp 中的“模型”如何用函数式编程语言实现?
Posted
技术标签:
【中文标题】Rails 类型的 webapp 中的“模型”如何用函数式编程语言实现?【英文标题】:How would the 'Model' in a Rails-type webapp be implemented in a functional programming language? 【发布时间】:2011-02-14 00:24:39 【问题描述】:在 Ruby on Rails、Django 和 Cakephp 等 MVC Web 开发框架中,HTTP 请求被路由到控制器,控制器获取通常持久保存到后端数据库存储的对象。这些对象代表用户、博客文章等内容,并且通常在其方法中包含用于权限、获取和/或改变其他对象、验证等的逻辑。
这些框架都非常面向对象。我最近一直在阅读函数式编程,它似乎吹捧了巨大的好处,例如可测试性、简洁性、模块化等。但是,我看到的大多数函数式编程示例都实现了诸如快速排序或斐波那契数列之类的琐碎功能,而不是复杂的网络应用程序。我查看了一些“功能性”Web 框架,它们似乎都很好地实现了视图和控制器,但在很大程度上跳过了整个“模型”和“持久性”部分。 (我说的更多是像 Compojure 这样的框架,它们应该是纯功能性的,而不是像 Lift 那样方便地使用 Scala 的 OO 部分作为模型的框架——但如果我在这里错了,请纠正我。)
我还没有很好地解释如何使用函数式编程来提供 OO 编程所提供的隐喻,即表映射到对象,并且对象可以具有提供强大的封装逻辑(例如权限和验证)的方法。此外,使用 SQL 查询来持久化数据的整个概念似乎违反了整个“副作用”概念。有人可以解释一下“模型”层将如何在功能编程的 Web 框架中实现吗?
【问题讨论】:
功能语言试图限制副作用是的。但限制总是在程序的范围内。数据存储和 IO 位于应用程序的边界之外,因此它们是可以接受的。一旦数据进入应用程序,那么该数据的转换和路由应该是可以理解和确定的。 【参考方案1】:不想抨击面向对象的 MVC 框架——我不了解 Rails,但 Django 在我眼中是一款出色的软件——我不确定对象关系映射是 particularly good metaphor1.
当然,在 OO 语言中,希望根据对象来考虑表似乎很自然,但在函数式语言中,根据表来考虑表是非常自然的。可以使用代数数据类型(在 Haskell 和其他静态类型函数语言中)或映射(也称为字典;将键映射到值的关联结构)轻松表示单行;然后一个表变成了一系列行,毕竟它甚至在数据库级别。因此,没有从表的 DB 构造到编程语言中可用的其他构造的特殊映射;您可以简单地在两侧使用表格。2
现在这绝不意味着必须使用 SQL 查询来操作数据库中的数据,因为抽象优于各种 RDBMS 的怪癖。由于您使用的是 Clojure 标签,因此您可能对ClojureQL 感兴趣,这是一种用于以通用方式与各种 DB 通信的嵌入式 DSL。 (请注意,它现在正在重新设计。)您可以使用一些这样的 DSL 来提取数据;使用纯函数处理由此获得的数据;然后显示一些结果,并可能将一些数据持久化回数据库(使用相同的 DSL)。
1 如果您认为将一项技术与越南战争进行比较有点极端,我想我同意,但这并不意味着这篇文章没有很好地说明原因人们可能不想陷入 ORM 的泥潭。
2 请注意,您可以在 OO 语言中使用相同的方法,并以与 FP 语言中相同的方式对 DB 后端进行抽象(请参阅下一段)。当然,您的 MVC 框架将不再看起来很像 Rails。
【讨论】:
【参考方案2】:查看Conjure web application framework 示例,了解如何在函数式编程语言中实现 MVC 框架。 Conjure 使用clj-record 作为模型层,它支持关联和验证。
【讨论】:
以上是关于Rails 类型的 webapp 中的“模型”如何用函数式编程语言实现?的主要内容,如果未能解决你的问题,请参考以下文章
如何编写迁移以重命名 Rails 中的 ActiveRecord 模型及其表?