Java to Clojure重写


97

我公司刚刚要求我用Clojure重写一个大型的(50,000行单行代码)Java应用程序(使用JSP和servlet的Web应用程序)。还有其他人知道我应该注意的提示吗?

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

更新资料

我进行了重写,并投入生产。这很奇怪,因为重写的速度如此之快,以至于大约需要6周的时间。因为仍然不需要很多功能,所以最终得到了大约3000行Clojure。

我听说他们对系统及其按自己要求的方式感到满意。唯一的缺点是,维护系统的人必须从头开始学习Clojure,他被踢入脚踢并尖叫。前几天我确实接到了他的电话,说他现在爱Lisp了。

另外,我也要对Vaadin表示赞赏。使用Vaadin可能会像Clojure一样节省大量时间,并且缩短代码。(请注意,Vaadin和ClojureScript均在后台使用Google的GUI框架。)


55
我想为贵公司工作。
mtyaka 2011年

4
好吧,欧洲的一些国防公司已经开始使用Clojure(我听说)。但不记得任何名字了:)
appshare.co

1
@Zubair:5万个Java LOC不在“大型”附近。这是一个非常小的项目。我这里有一个250KLOC到300KLOC Java项目,它是中等大小……最好。
语法T3rr0r 2011年

5
实际上,我可能会提到代码库的大小而犯了一个错误,因为公平地说,减少代码大小并不是重写的目的。目的是双重的:1)使代码库更易于理解,因此维护代码更便宜2)允许该工具的用户使用Web浏览器中的Clojure编辑器扩展产品(使用eval和其他动态Clojure优点,这样做成本更高)用Java做)
appshare.co

1
嘿...刚看到这个老问题,想知道重写的过程如何?
levand 2011年

Answers:


82

最大的“翻译问题”可能会从Java / OOP方法学转向Clojure /功能编程范式。

特别是,“ Clojure方法”不是在对象内部具有可变状态,而是要清楚地区分出可变状态并开发纯净(无副作用)功能。您可能已经知道所有这些了:-)

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

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

  2. 开发纯的,面向业务逻辑的功能的小型库,这些库可在这些不可变的结构上运行(例如,“向购物车中添加商品”)。您不需要一次完成所有这些操作,因为稍后可以轻松添加更多内容,但是这样做有助于尽早进行一些测试以方便测试并证明您的数据结构可以正常工作……..您实际上可以在REPL上开始以交互方式编写有用的东西

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

  4. 编写涵盖以上所有内容的单元测试(例如,使用clojure.test)。这在像Clojure这样的动态语言中尤为重要,因为a)您没有太多来自静态类型检查的安全网,并且b)确保在构建过多基础结构之前,您的低级结构能够正常工作他们的顶端

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

  6. 选择合适的整体Web框架-Clojure已经有很多了,但是我强烈建议Ring-观看这段出色的视频“ 将它们捆绑在一起的一环 ”,再加上FleetEnliveHiccup,具体取决于您的模板设计理念。然后使用它来编写您的表示层(具有“将购物车翻译成适当的HTML片段之类的功能”)

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

由于它大致代表了代码中的依存关系顺序,因此,这大致就是我要解决该问题的顺序,因此适合“自下而上”的开发工作。尽管当然采用了良好的敏捷/迭代风格,您可能会发现自己早早地开发了可证明的最终产品,然后很频繁地跳回早期步骤以扩展功能或根据需要进行重构。

ps如果您遵循上述方法,那么我会着迷于与50,000行Java的功能相匹配需要多少行Clojure。

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

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

4
Nitpick回复:“确定要用于管理每个部件可变的应用程序级状态的Clojure的STM参考类型中的哪一个”:只有一种STM参考类型。其他IRef不涉及STM。否则,看起来像是可靠的建议。

嗯...我想我将引用,代理和原子算作Clojure STM /并发系统的一部分。例如,它们都支持验证器,并且代理与事务的提交协调。但我明白你的意思,裁判是“主要”交易模型。将进行快速修改。
mikera 2011年

2
如果可以的话,我可以再给+1。我看了您引用的两个视频,它们很棒。谢谢。
jdl 2011年

1
现在不推荐使用noir。我想您不得不提到compojure而不是noir。
hsestupin

一环绑定链接已断开!
亚当·阿罗德

5

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


Servlet,JSP,内置的持久性框架(已有10年历史)和pojos,但没有EJB
appshare.co

4
Servlet可以很容易地用Ring + Compojure IMHO替换,而JSP则可以用StringTemplate(或FreeMarker / Velocity模板)替换。Clojure中的持久性将不同于Java。如果需要关系映射,可以查看Clj-Record和SQLRat(还不是很成熟)。AFAICT目前,ClojureQL仅支持MySQL和PostgreSQL。ccsql当前不允许在列名称中使用下划线的限制可能令人感到意外。我认为在需要时讨论Clojure列表上的开发方面将很有用。在这个项目上祝你好运!
Shantanu Kumar

从那个项目开始,我使用Clojure和Clojurescript(nemcv.com)制作了另一个应用程序,现在我使用Ring,尝试使用ClojureQL,但是切换到Korma进行数据库访问。您可以在github.com/zubairq/coils
appshare.co上

4

我发现最困难的部分是考虑数据库。做一些测试以找到您想要在其中使用的正确工具。


1
好吧,我已经尝试使用clojureql进行数据访问,但是它与Java风格的数据库访问完全不同,后者都是基于对象的。出于兴趣,您对Java使用了什么数据库访问权限,对Clojure使用了什么?
appshare.co

1
我们最终重新考虑了很多东西,并选择了mongodb,因为clojure数据结构的持久性非常自然
LenW 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.