Java 到 Clojure 重写

标签 java clojure vaadin

我的公司刚刚要求我在 Clojure 中重写一个较大的(50,000 行代码)Java 应用程序(一个使用 JSP 和 servlet 的 Web 应用程序)。有没有其他人知道我应该注意什么?

请记住,我非常了解 Java 和 Clojure。

更新

我进行了重写并投入生产。很奇怪,因为重写最终进行得如此之快,以至于它在大约 6 周内完成。因为不需要很多功能,它最终还是更像是 3000 行 Clojure。

我听说他们对这个系统很满意,它完全按照他们的意愿行事。唯一的缺点是维护系统的人必须从头开始学习 Clojure,他被拖入其中,又踢又叫。前几天我确实接到了他的电话,说他现在喜欢 Lisp 了……很有趣 :)

另外,我应该好好提一下 Vaadin。使用 Vaadin 可能会像 Clojure 一样节省大量时间和缩短代码。Vaadin 仍然是我使用过的顶级 Web 框架,尽管现在我正在愤怒地学习 ClojureScript! (请注意,Vaadin 和 ClojureScript 都在幕后使用 Google 的 GUI 框架。)

最佳答案

最大的“翻译问题”可能是从 Java/OOP 方法论到 Clojure/函数式编程范式。

特别是,“Clojure 方式”不是在对象内具有可变状态,而是明确地分离出可变状态并开发纯(无副作用)函数。你可能已经知道这一切了:-)

无论如何,这种理念往往会导致某种“自下而上”的开发风格,您将最初的努力集中在构建正确的工具集来解决您的问题上,然后最后将它们组合在一起。这可能看起来像这样

  • 识别关键数据结构并将它们转换为不可变的 Clojure 映射或记录定义。不要害怕嵌套大量不可变映射 - 由于 Clojure 的持久数据结构,它们非常高效。值得一看this video了解更多信息。
  • 开发针对这些不可变结构运行的纯业务逻辑功能的小型库(例如“将商品添加到购物车”)。你不需要一次做所有这些,因为以后很容易添加更多,但它有助于尽早做一些以促进测试并证明你的数据结构正在工作......无论哪种方式实际上,您可以在 REPL
  • 上开始以交互方式编写有用的东西。
  • 单独开发数据访问例程,可以根据需要将这些结构持久化到/从数据库或网络或遗留 Java 代码。保持这种分离的原因是您不希望持久性逻辑与您的“业务逻辑”功能捆绑在一起。您可能想查看 ClojureQL为此,尽管包装您喜欢的任何 Java 持久性代码也很容易。
  • 编写涵盖以上所有内容的单元测试(例如使用 clojure.test )。这在像 Clojure 这样的动态语言中尤其重要,因为 a) 你没有那么多来自静态类型检查的安全网,b) 在你构建太多之前,它有助于确保你的低级构造运行良好其中最重要的
  • 决定如何使用 Clojure 的引用类型(变量、引用、代理和原子)来管理每个部分的可变应用程序级状态。它们都以类似的方式工作,但根据您尝试执行的操作具有不同的事务/并发语义。 Refs 可能会成为您的默认选择——它们允许您通过将任何代码包装在 (dosync ...) 块中来实现“正常”的 STM 事务行为。
  • 选择正确的整体 Web 框架 - Clojure 已经有很多,但我强烈推荐 Ring - 观看这个优秀的视频“One Ring To Bind Them”加上 FleetEnliveHiccup取决于你的模板哲学。然后使用它来编写您的表示层(具有诸如“将此购物车转换为适当的 HTML 片段”之类的功能)
  • 最后,使用上述工具编写您的应用程序。如果您正确地完成了上述步骤,那么这实际上会很容易,因为您将能够通过适当组合各种组件和很少的样板来构建整个应用程序。

  • 这大致是我将要解决的问题的顺序,因为它广泛地代表了代码中依赖项的顺序,因此适用于“自下而上”的开发工作。当然,在良好的敏捷/迭代风格中,您可能会发现自己很早就推进到可演示的最终产品,然后经常跳回到早期步骤以根据需要扩展功能或重构。

    附言如果您确实遵循上述方法,我会很高兴听到需要多少行 Clojure 才能匹配 50,000 行 Java 的功能

    更新 :由于这篇文章最初是写的,因此出现了一些属于“必须检查”类别的额外工具/库:
  • Noir - 建立在 Ring 之上的 Web 框架。
  • Korma - 用于访问 SQL 数据库的非常好的 DSL。
  • 关于Java 到 Clojure 重写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5232654/

    相关文章:

    java - 图像处理 - 曝光对图像的影响

    java - 为什么要在 Double-Checked-Locking 中添加第二个测试?

    html - 带打嗝的内联样式

    class - 带类的Clojure案例陈述

    css - 通过覆盖应用在其上的默认 css 自定义 Vaadin 详细信息展开图标

    java - 读取文件并将名称和数字存储在两个数组中

    java - 如何在嵌入式 Web 服务器中部署 GWT 应用程序

    functional-programming - Clojure 中的可插入向量处理单元

    javascript - 在 vaadin 8 中将文本复制到剪贴板

    java - 找不到适用于jdbc:hsqldb:file:\dir\to\db的驱动程序