重构 基于 Rails 1.X 的核心项目的重构?

msg7086 · 2015年06月03日 · 最后由 swordray 回复于 2015年06月07日 · 8159 次阅读

接手一个公司核心项目,初版代码是 2007 年开发的,用的是 Rails 1.X,没有测试也没有 Gemfile,代码量 2 万行不到。后端有其他语言逻辑(API),前端基于 Flex(也是 2007 年技术),所以只作中间层 API,使用 XML 通讯(以后可能会改 JSON,还没确定)。

现在公司打算重构到现代版本,升级到 Ruby 2 Rails 4,加入测试覆盖,以后可能会把 Flex 也换掉。

那么问题来了。应该如何逐步重构?(或者应该直接推翻了新建项目再移植原有功能?)

匿名 #1 2015年06月03日

推翻了,重做吧:那些 Gem 包肯定一升级上去,全部报错的,改错要改到什么时候。版本相差太远了...

#1 楼 @chanshunli 如果重做的话,有什么比较理想的步骤吗? 毕竟人手不足,全部重写的话时间代价太大了,有没有什么思路可以减少时间风险的?

#2 楼 @msg7086 先给现有版本写测试,然后基于测试写新的版本

#3 楼 @suupic 我一开始也是这么想。问题是 Rails1.X 我不会啊……

重构里面强调,如果差异很大,重写的代价低于重构,那么就应该重写。 测试用例应该是用新版本写,但是功能和测试数据基于老版本。

你可以这么想,就当作这个遗留版本是一份需求文档,现在你要用 Ruby 2 + Rails 4 开始开发它,就按照正常流程来。如果人手不够,要么延长交付时间,要么增加人手,如果两者都不行,那是管理的问题。

匿名 #6 2015年06月04日

#2 楼 @msg7086 按照 @kgen 的做法 测试用例应该是用新版本写,但是功能和测试数据基于老版本。 :plus1:

这篇文章 倒是写了 cookpad 是如何升级 ruby 跟 rails 的,虽然基本都是写如何升级 ruby 版本,Orz

升级 rails 它给的建议是, 一方、Rails のバージョンアップでは、バージョン間差異をモンキーパッチで吸収しにくい為、バージョン移行用のブランチ内で作業する必要があります (本稿で扱っているクックパッドは、Rails がバージョン 1 の頃のコードベースを使い続け、Rails のバージョンアップを何度か実施し、現在は Rails 3.2 系で運用しています)。

这是无责任简单翻译 但是一方面,对于 Rails 的版本升级,很难写出各版本差异之间的 monky patch,因此升级版本的时候需要在 branch 中进行(本文所涉及到的 cookpad 来说的话,Rails 在使用 version 1的代码的基础之上,重复了好几次Rails的版本升级,现在系统运行在Rails 3.2 上)

给现有系统只写黑盒 acceptance test, 尽量 cover 关键逻辑。新系统从单元测试重头开发。

#7 楼 @ywjno 多谢。文章里果然看到了很多很多今天看到的 ruby1.8 系的坑。等上班的时候仔细研究一下 w

(话说クックパッド是 cookpad 网站……

之前有 follow 一个老外的项目,该项目最初是基于 rails2.3 的,升级 rails 的步骤是 rails2.3 -> rails3.0 -> rails3.x -> rails4。。

#10 楼 @Tim_Lang 我其实也打算这样搞。不过历史遗留坑实在太多,打算还是先熟悉一下公司的产品线再看接下去怎么走。

#9 楼 @msg7086 多谢回复,已修改原文(请原谅早上起来头脑不清醒的翻译,QwQ

我来说下我的方案吧,在两个以上的公司做过了。

比如要重构旧 Rails 1.x 上面的/users API:

  1. 另起一个 Ruby 2 + Rails 4 的项目,在上面写/users API。要求的 request params 可以和原来不一样,也可以一样。Rails 4 也连原来的数据库。
  2. 部署 Rails 4。
  3. 在 nginx 上面写一个 location /users,/users API 将从由 Rails 1.x 处理改到由 Rails 4 来处理。

这样无痛地慢慢地把原来 Rails 1.x API 移过来。

如果原来的 request 格式很难看(比如不是 Rails 那一套 RESTful 的风格),也可以在 nginx 里面进行改写。

#13 楼 @prajnamas 赞,逐步替换,保证了项目一直可用。

搞清楚业务逻辑重做吧~ 1.我公司也有一个项目 1.x 的升到 2.x 后就一直没升,一直稳定运行。

重构的成本远远高于重做

需要 登录 后方可回复, 如果你还没有账号请 注册新账号