最大的“转换问题”可能是从Java / OOP方法到Clojure /函数式编程范式。
特别是,“Clojure方式”不是在对象中具有可变状态,而是明确分离出可变状态并开发纯(无副作用)功能。你可能已经知道了:-)
无论如何,这种理念往往会导致某种“自下而上”的开发风格,在这种风格中,你把最初的精力集中在构建正确的工具集来解决你的问题上,最后将它们插入到一起。这可能看起来像这样
识别关键数据结构并将其转换为不可变的Clojure映射或记录定义。不要害怕嵌套大量不可变的映射 - 由于Clojure的持久数据结构,它们非常有效。值得观看此视频以了解更多信息。
开发在这些不可变结构上运行的纯业务逻辑函数的小型库(例如,“将商品添加到购物车”)。您不需要一次完成所有这些操作,因为以后很容易添加更多,但是尽早做一些操作以方便测试并证明您的数据结构正在工作是有帮助的.....无论哪种方式,在这一点上,您实际上都可以在REPL上以交互方式开始编写有用的东西
单独开发数据访问例程,这些例程可以根据需要将这些结构持久保存在数据库或网络或旧版 Java 代码中。保持这种独立性的原因是,您不希望持久性逻辑与“业务逻辑”函数捆绑在一起。你可能想看看ClojureQL,尽管包装任何你喜欢的Java持久性代码也很容易。
编写涵盖上述所有内容的单元测试(例如,使用clojure.test)。这在像Clojure这样的动态语言中尤其重要,因为a)你没有那么多来自静态类型检查的安全网,b)在你在上面构建太多之前,确保你的低级结构运行良好是有帮助的。
确定如何使用 Clojure 的引用类型(vars、refs、代理和原子)来管理每个部分的可变应用程序级状态。它们都以类似的方式工作,但具有不同的事务/并发语义,具体取决于您要执行的操作。Refs可能是你的默认选择 - 它们允许你通过将任何代码包装在(dosync ...)块中来实现“正常”的STM事务行为。
选择正确的整体Web框架 - Clojure已经有很多了,但我强烈建议Ring - 请参阅这个优秀的视频“One Ring To Bind Them”以及Fleet或Enlive或Hiccup,具体取决于您的模板哲学。然后使用它来编写您的表示层(具有“将此购物车转换为适当的HTML片段”之类的功能)
最后,使用上述工具编写应用程序。如果您已经正确完成了上述步骤,那么这实际上将很容易,因为您将能够通过各种组件的适当组合来构建整个应用程序,而样板文件很少。
这大致是我要解决的问题的顺序,因为它广泛地代表了代码中依赖项的顺序,因此适合于“自下而上”的开发工作。当然,在良好的敏捷/迭代风格中,你可能会发现自己很早就向前推进到一个可证明的最终产品,然后非常频繁地跳回到早期的步骤,以根据需要扩展功能或重构。
p.s. 如果你遵循上述方法,我会很着迷地听到需要多少行Clojure才能匹配50,000行Java的功能。
更新:由于这篇文章最初是写的,因此出现了一些额外的工具/库,它们属于“必须签出”类别:
-
Noir - 建立在Ring之上的Web框架。
-
Korma - 一个非常好的DSL,用于访问SQL数据库。