将现有凌乱的webapp迁移到优雅的MVC的最佳方法是什么?

我大约一个月前加入了一家新公司。 该公司规模相当小,并且具有非常强大的“初创”感觉。 我是一个由另外3人组成的团队的Java开发人员。 该公司主要为企业/商业类型的人销售服务,以便彼此进行通信。

我一直在努力的主要事情之一就是公司的主要网站 – 从中​​出售服务,现有用户登录查看服务并支付账单,新用户可以报名参加试用目前,这是一个部署在Tomcat上的JSP应用程序,可以通过公司自己编写的持久层访问数据库。

我在这里反复且越来越沮丧(我对整体工作非常满意,所以这不是“哦,不,我不喜欢我的工作” – 类型的post)是缺少任何更大的设计或此Web应用程序的体系结构。 该应用程序由几十个JSP页面组成,Servlet或Bean中几乎没有逻辑或任何其他类型的框架。 许多JSP页面都是数千行代码,它们jsp:include其他JSP页面,业务逻辑与HTML混合,经常使用的代码片段(如获取Web服务连接)被剪切和粘贴而不是重用换句话说,应用程序是一团糟。

公司内部有一些声音,试图重新设计这个网站,以便更好地适应MVC; 我认为开发人员和高层人员开始意识到,目前的意大利面条代码模式不可持续或非常容易扩展,无法为用户添加更多function。 高层和开发人员对完全重写事物持谨慎态度(有充分理由,因为这意味着需要几周或几个月的时间重写现有function),但我们已经讨论过(慢慢地)将网站的某些区域写入新框架。

有哪些最佳策略可以将应用程序和代码库转移到这个方向? 作为一名开发人员,我怎样才能真正帮助实现这一目标,并且很快就能看到像工作中的那个混蛋新人并且告诉每个人他们写的东西是废话? 当您遇到这种事情时,您在自己的工作经历中使用过任何经过validation的策略或经验吗?

你最好的选择可能是随着你的进展慢慢地重构它。 我们很少有资源可以完全从头开始,其中包含许多业务规则。 当您花费数月时间开发一个比您更换的错误更多的错误的应用程序时,管理层真的很讨厌它。

如果您有机会从头开始构建任何单独的应用程序,请使用其中的所有最佳实践并使用它来演示它们的有效性。 如果可以,请将这些想法逐步纳入旧应用程序。

首先拿起Michael Feather 有效使用遗留代码的副本。 然后确定如何最好地测试现有代码。 最糟糕的情况是你只是坚持一些高级回归测试(或根本没有),如果你很幸运,将会进行unit testing。 然后,这是一个缓慢稳定的重构,希望同时添加新的业务function。

根据我的经验,应用程序的“优雅”通常与数据库设计有关,而不是任何东西。 如果您拥有出色的数据库设计,包括定义良好的存储过程接口,那么无论您使用何种平台,都可以使用良好的应用程序代码。 如果您的数据库设计很差 ,无论您使用什么平台,您都将很难构建优雅的应用程序代码,因为您将不断补偿数据库。

当然,在与小之间有足够的空间,但我的观点是,如果你想要好的应用程序代码,首先要确保你的数据库符合要求。

这在仅处于维护模式的应用程序中更难做到,因为很难说服管理层重写已经“正常工作”的东西值得做。 我首先将MVC的原理应用于您能够处理的任何新代码(即将业务逻辑移动到类似于模型的东西,将所有布局/视图代码放在一个地方)

随着您在MVC中获得新代码的经验,您可以开始看到巧妙地更改现有代码的机会,以便它也符合要求。 这可能是一个非常缓慢的过程,但如果您能够展示这种方式的好处,那么您将能够说服其他人并让整个团队参与进来。

我同意缓慢的重构方法; 例如,将复制粘贴的代码解压缩到任何适当的Java范例(一个类,或许?或者更好,使用现有的库?)。 如果您的代码非常干净简洁,但仍然缺乏整体架构策略, 那么您将能够更轻松地将事物融入整体架构中。

最好的方法是打印出代码,将其折叠起来然后扔出去。 甚至不回收纸张。

你有一个用1000多行JSP编写的应用程序。 它可能有一个令人难以置信的领域模型(如果它甚至有一个)并且不仅仅是MIX演示与业务逻辑,它将它混合并坐在那里并持续搅拌数小时。 没有办法取出蹩脚的代码并进入MVC Controller类并且仍在做正确的事情,你最终会得到一个带有贫血域模型的MVC应用程序或者像数据库调用这样的东西在Controller代码中,你仍然失败了。

您可以尝试一个新的应用程序来做正确的事情,然后让两个应用程序相互通信,但这本身就是新的复杂性。 如果你刚刚从头开始,你可能会做同样多的工作,但是你可能会更容易想要说服你的老板这是一个更好的方法。

迭代重构。 还要寻找可以在新框架中完全完成的新function,以此来展示新框架的价值。

我的建议是找到不需要导入其他JSP的稀有页面,或者只有很少的导入。 将每个导入的JSP视为黑盒子,并围绕它们重构这些页面(迭代地,测试每个更改并确保它在继续之前有效)。 清理完这些内容后,您可以继续查找包含越来越多导入的页面,直到最后您重构了导入。

在重构时,请注意尝试访问未提供给页面的资源的部分,并尝试将其转发给控制器。 例如,访问数据库的任何东西都应该在控制器内部,让JSP处理控制器通过转发给它的信息的显示。 通过这种方式,您将为每个页面开发几个servlet或servlet之类的东西。 我建议使用基于前端控制器的框架进行这种重构(从个人经验我推荐Spring及其Controller接口),这样每个控制器都不是一个单独的Servlet,而是从一个适当映射的servlet委托给它。

对于控制器,最好一次性完成数据库命中,而不是逐个尝试它们。 用户可以并且通常可以容忍页面加载,但是如果将所有数据库数据提供给呈现代码而不是呈现代码挂起并且在尝试读取另一个时不向客户端提供数据,则页面输出将快得多。来自数据库的一段数据。

我感受到你的痛苦,祝你好运。 现在,当你必须维护一个滥用Spring Webflow的应用程序时,那是另一个故事:)