Java to Clojure rewrite

2022-08-31 10:46:53

我的公司刚刚要求我在Clojure中重写一个大的(50,000行代码)Java应用程序(使用JSP和servlets的Web应用程序)。有没有人得到关于我应该注意什么的提示?

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

更新

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

我听说他们对这个系统感到满意,它完全按照他们想要的方式做。唯一的缺点是,维护系统的家伙必须从头开始学习Clojure,他被拖进去踢和尖叫。前几天我确实接到他的电话,说他现在喜欢Lisp。有趣的:)

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


答案 1

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

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

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

  1. 识别关键数据结构并将其转换为不可变的Clojure映射或记录定义。不要害怕嵌套大量不可变的映射 - 由于Clojure的持久数据结构,它们非常有效。值得观看此视频以了解更多信息。

  2. 开发在这些不可变结构上运行的纯业务逻辑函数的小型库(例如,“将商品添加到购物车”)。您不需要一次完成所有这些操作,因为以后很容易添加更多,但是尽早做一些操作以方便测试并证明您的数据结构正在工作是有帮助的.....无论哪种方式,在这一点上,您实际上都可以在REPL上以交互方式开始编写有用的东西

  3. 单独开发数据访问例程,这些例程可以根据需要将这些结构持久保存在数据库或网络或旧版 Java 代码中。保持这种独立性的原因是,您不希望持久性逻辑与“业务逻辑”函数捆绑在一起。你可能想看看ClojureQL,尽管包装任何你喜欢的Java持久性代码也很容易。

  4. 编写涵盖上述所有内容的单元测试(例如,使用clojure.test)。这在像Clojure这样的动态语言中尤其重要,因为a)你没有那么多来自静态类型检查的安全网,b)在你在上面构建太多之前,确保你的低级结构运行良好是有帮助的。

  5. 确定如何使用 Clojure 的引用类型(vars、refs、代理和原子)来管理每个部分的可变应用程序级状态。它们都以类似的方式工作,但具有不同的事务/并发语义,具体取决于您要执行的操作。Refs可能是你的默认选择 - 它们允许你通过将任何代码包装在(dosync ...)块中来实现“正常”的STM事务行为。

  6. 选择正确的整体Web框架 - Clojure已经有很多了,但我强烈建议Ring - 请参阅这个优秀的视频“One Ring To Bind Them”以及FleetEnliveHiccup,具体取决于您的模板哲学。然后使用它来编写您的表示层(具有“将此购物车转换为适当的HTML片段”之类的功能)

  7. 最后,使用上述工具编写应用程序。如果您已经正确完成了上述步骤,那么这实际上将很容易,因为您将能够通过各种组件的适当组合来构建整个应用程序,而样板文件很少。

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

p.s. 如果你遵循上述方法,我会很着迷地听到需要多少行Clojure才能匹配50,000行Java的功能。

更新:由于这篇文章最初是写的,因此出现了一些额外的工具/库,它们属于“必须签出”类别:

  • Noir - 建立在Ring之上的Web框架。
  • Korma - 一个非常好的DSL,用于访问SQL数据库。

答案 2

您当前的项目包括 Java 的哪些方面?日志记录,数据库事务,声明性事务/ EJB,Web层(您提到了JSP,servlet)等。我注意到Clojure生态系统有各种微框架和库,其目标是完成一项任务,并做好它。我建议根据您的需求(以及它是否会在大型项目中扩展)评估库,并做出明智的决定。(免责声明:我是沥青框架的作者)另一件需要注意的事情是构建过程 - 如果您需要复杂的设置(开发,测试,暂存,生产),您可能必须将项目拆分为模块,并为构建过程编写脚本以方便。


推荐