我大约一个月前加入了一家新公司。该公司规模相当小,并且具有非常强大的“初创”感觉。我是一个由另外3人组成的团队的Java开发人员。该公司主要为企业/企业型人员销售服务,以便彼此进行沟通。
我过去和将要工作的主要事情之一是公司的主要网站 - 从中销售服务,现有用户登录以检查他们的服务并支付账单,新用户可以注册目前,这是一个部署在Tomcat上的JSP应用程序,可以通过公司自己编写的持久层访问数据库。
我在这里遇到了反复且越来越多的挫折(我对整体工作非常满意,所以这不是“哦,不,我不喜欢我的工作” - 类型的帖子)是缺乏任何此Web应用程序的更大设计或体系结构。该应用程序由几十个JSP页面组成,Servlet或Bean中几乎没有逻辑或任何其他类型的框架。许多JSP页面都是数千行代码,它们jsp:include
其他JSP页面,业务逻辑与HTML混合在一起,经常使用的代码片段(如获取Web服务连接)被剪切和粘贴而不是重复使用等等。换句话说,应用程序是一团糟。
公司内部有一些声音试图重新设计这个网站,以便更好地适应MVC;我认为开发人员和高层人员开始意识到目前的意大利面条代码模式是不可持续的,或者很容易扩展,以便为用户添加更多功能。高层和开发人员对完全重写事物持谨慎态度(有充分理由,因为这意味着需要几周或几个月的时间重写现有功能),但我们已经讨论过(慢慢地)将网站的某些区域写入新的框架。
有哪些最佳策略可以将应用程序和代码库转移到这个方向?作为一名开发人员,我怎么能真正帮助实现这一目标,并且很快就能看到像工作中的那个混蛋新人并且告诉每个人他们写的是废话?当你遇到这种事情时,你在自己的工作经历中使用过的经过验证的策略或经验吗?
答案 0 :(得分:11)
你最好的选择可能是随着你的进展慢慢地重构它。我们很少有资源可以完全从头开始,其中包含许多业务规则。当你花费数月时间开发一个比你更换的错误更多的错误的应用程序时,管理层真的很讨厌它。
如果您有机会从头开始构建任何单独的应用程序,请使用其中的所有最佳实践并使用它来证明它们的有效性。如果可以,请将这些想法逐步纳入旧应用程序。
答案 1 :(得分:3)
首先拿起Michael Feather的工作Effectively with Legacy Code的副本。然后确定如何最好地测试现有代码。最糟糕的情况是你只是坚持一些高级回归测试(或根本没有),如果你很幸运,将会进行单元测试。然后,这是一个缓慢稳定重构的案例,希望同时添加新的业务功能。
答案 2 :(得分:2)
根据我的经验,应用程序的“优雅”通常更多地与数据库设计有关。如果你有一个伟大的数据库设计,包括一个定义良好的存储过程接口,无论你使用什么平台,都可以使用好的应用程序代码。如果你有差的数据库设计,无论你使用什么平台,你都会很难建立优雅的应用程序代码,因为你将不断补偿数据库。
当然,好和穷人之间有足够的空间,但我的观点是,如果你想要好的应用程序代码,首先要确保你的数据库是鼻烟。
答案 3 :(得分:2)
在仅处于维护模式的应用程序中这很难做到,因为很难说服管理层重写已经“正常工作”的东西值得做。我首先将MVC的原理应用于您能够处理的任何新代码(即将业务逻辑移动到类似于模型的东西,将所有布局/视图代码放在一个地方)
随着您在MVC中获得新代码的经验,您可以开始看到巧妙地更改现有代码的机会,以便它也符合要求。这可能是一个非常缓慢的过程,但是如果你能够展示这种做法的好处,那么你将能够说服其他人并让整个团队参与其中。
答案 4 :(得分:1)
我同意缓慢的重构方法;例如,获取复制粘贴的代码并将其提取到适当的Java范例(一个类,或许?或者更好,使用现有的库?)。如果您的代码非常干净简洁,但仍然缺乏整体架构策略,那么那么您将能够更轻松地使整个架构更适合。
答案 5 :(得分:1)
最好的方法是打印出代码,将其弄皱,然后将其丢弃。甚至不回收纸张。
你有一个用1000多行JSP编写的应用程序。它可能有一个令人难以置信的领域模型(如果它甚至有一个)并且不仅仅是MIX演示与业务逻辑,它将它混合并坐在那里并持续搅拌数小时。没有办法取出蹩脚的代码并进入MVC Controller类并仍然做正确的事情,你最终会得到一个带有贫血域模型的MVC应用程序或者有类似数据库调用之类的东西在Controller代码中,你仍然失败了。
你可以尝试一个新的应用程序做正确的事情然后让两个应用程序相互交谈,但这本身就是新的复杂性。如果你刚从头开始,你可能会做同样多的工作,但是你可能会更容易想要说服你的老板这是一个更好的方法。
答案 6 :(得分:0)
迭代重构。还要寻找可以在新框架中完全完成的新功能,作为展示新框架价值的一种方式。
答案 7 :(得分:0)
我的建议是找到不需要导入其他JSP的稀有页面,或者只有很少的导入。将每个导入的JSP视为黑盒子,并围绕它们重构这些页面(迭代地,测试每个更改并确保它在继续之前有效)。清理完这些内容后,您可以继续查找包含越来越多导入的页面,直到最后您重构了导入。
重构时,请注意尝试访问未提供给页面的资源的部分,并尝试将其转发给控制器。例如,访问数据库的任何东西都应该在控制器内部,让JSP处理控制器通过转发给它的信息的显示。通过这种方式,您将为每个页面开发几个servlet或servlet之类的东西。我建议使用基于前端控制器的框架进行这种重构(从个人经验我推荐Spring及其Controller接口),这样每个控制器都不是一个单独的Servlet,而是从一个适当映射的servlet委托给它。
对于控制器,最好一次性完成数据库命中,而不是零碎地尝试它们。用户可以并且通常可以容忍页面加载,但是如果将所有数据库数据提供给呈现代码而不是呈现代码挂起并且在尝试读取另一个时不向客户端提供数据,则页面输出将快得多。来自数据库的一段数据。
我感受到你的痛苦,祝你在这一努力中幸运。现在,当你必须维护一个滥用Spring Webflow的应用程序时,那是另一个故事:)