瞎扯淡 Rails- 让我欢喜让我忧!

jasonliu · 2016年03月15日 · 最后由 sammo 回复于 2016年06月24日 · 12927 次阅读
本帖已被设为精华帖!

从 12 年毕业到现在,前前后后经历了 2 个 rails 项目,从机缘巧合接触 ruby,到专职从事 rails 开发,再到暂时告别 rails,我有太多的感触。我见过有人把 rails 视作神兵利器,也见过有人将其视作花拳绣腿,而我从来不愿意参与这些口舌之争,我只觉得写 rails 挺开心,这就足够了。但是悲催的是,我所经历的 rails 项目,都让我觉得非常郁闷!

都说幸福的人都一样,不幸的人各有各的不幸!但是不幸的 rails 代码大多数都是相同的。

不幸之一:Fat View, Fat Controller

Rails 采用了 MVC 的架构:

  • Model: 处理数据及业务逻辑
  • Controller: 处理 web 请求,是模型层和视图层沟通的桥梁
  • View: 向浏览器提供数据,显示用户界面

rails 社区一直推荐 fat model, thin controller (也有人持不同意见)。与数据库查询和业务逻辑相关的均会放在 model 层,视图层根据请求的参数选择合适的模型并向视图层返回数据,而视图层只根据接受的数据渲染页面。但我见过很多人把业务逻辑放在 controller,动不动就是几百行代码,视图层还掺杂着数据库操作,erb 模版已经够混乱了,再加上各种 where, find_by...... 欲哭无泪啊!而这还不是问题的关键,关键是 Fat View, Fat Controller 会导致代码难以测试(咋们就不追求啥 BDD 了,有这个问题的基本上都不会有测试)。视图层的代码会根据请求参数的不同输出不同的结果,本身测试就很麻烦,如果再掺杂业务逻辑(数据库操作,异步任务,第三方接口调用等),测试复杂度急剧上升,所以很多的开源项目都会放弃控制层的测试,前提是控制层的代码简单的不需要测试,因为它本身就是处理请求的,不是处理业务的。

不幸之二:没有测试用例

如果有前面的不幸,这个不幸必然发生。曾经有位技术总监面试我的时候跟我说:“我看你以前有持续集成相关的工作经验,我希望你加入公司以后,可以帮助项目搭建一套 CI 系统...... ” 当我从 gitlab 克隆下代码,翻开 rspec 目录一看——空空如也!心中直呼:臣妾做不到啊!!!

可以弥补测试用例的前提是:

  • 没有犯第一个错误,或者说是犯的还不是很严重;
  • 项目还处于萌芽期。高速成长的项目不会给你时间去填补以前的坑,弥补测试用例或多或少都会涉及到重构某些方法,而重构本身就回有引入 bug 的风险,尤其是对本身就没有测试用例的方法进行重构,风险还会增加。稳定的项目也不值得去弥补缺失的测试用例,最好保证新添加的特性没有问题。
  • 说服你的同事,我觉得这个是最难的。

其实没有测试用例的最大痛苦在于,明明代码写的很烂,你却不敢动!!!

不幸之三:没有 code review

个人觉得要远离没有 code review 的公司,是否有 code review 并不是某个人或某个团队可以决定的,通常是一家公司的风格,价值观所决定的,如果开发者本身连研发的时间都不能自己评估和决定,还怎么去保证质量呢。ruby 本身做为一门动态语言,自由度灵活度都很高,我见过把 ruby 写的像 C 语言一样的。如果你待的 ruby 团队没有 code review,建议你早点离职,因为最后离职的人总是最痛苦的,他要接下所有人留下的烂摊子。

不幸之四:过度依赖或滥用 gem 包

gem 包的好处显而易见,它可以极大的加快你的开发进程。登录认证用 Devise,权限管理 Cancancan, 样式用 Bootstrap, 部署用 Capistrano...... 在开发一个功能的时候,你首先会想是否有现成的 gem 包实现这个功能。这很正常,我也是这样,不去重复去发明轮子。但是在用一个 gem 之前,至少要看几个指标:

  • start 数够不够多(个人觉得最低不得少于 50)
  • 更新是否频繁(如果超过一年都没有更新,提的 issue 也没有人处理,最好慎用)
  • 文档是否齐全

有人会说,我的 Gemfile 里面只加了 20 个 gem 包啊,也没多少啊!但每个 gem 包本身会依赖于其它的 gem,rails 本身也会默认使用很多 gem 包,实际上你安装的 gem 包数量会超过 100 个,甚至 200 个都有可能。这么多的 gem 包不仅占内存,导致启动慢,有的 gem 包也会有内存泄漏的风险。我也见过有人自己写了个 gem 包直接在项目上用,我鼓励这样做,但是自己的写的 gem 包至少有基本的容错处理,异常处理吧。

小结

Rails 上手的门槛真的很低,我见过非科班出身,做产品,做设计的用 rails 写应用,写的还不错,但我也见过一些有经验的程序员,使用了一两年的 rails,依然写的马马虎虎。这不奇怪,有些人是真的对此感兴趣,有的人是因为 “工作需要” 而已。很高兴的是,有越来越多的公司开始使用 ruby,很担忧的是,随着越来越多的人接触到 ruby 和 rails,他们可能会被一些不良代码 “吓倒 “,从此脱离 rails。从头写一个项目的机会是很难得的,如果你有机会从头开始写一个 rails 项目,我希望你可以了解一些 rails 的最佳实践或者绕过一些 ” 坑 “。

强烈推荐一篇文章:top-10-mistakes-that-rails-programmers-make 译文10 个最常见的 Rails 编程错误(很久之前翻译的,英文水平有限,见谅!)

这篇文章最经典的一句话是: rails 很好用,但是也很容易被滥用!

我所遇到的问题在这篇文章都有提到,希望对即将踏上 rails 之旅的伙伴有所帮助!

现在公司里的项目就在享受问题一 + 二 + 三。 没有问题四纯粹是因为我们连 Gem 都还没用上,还在用 Plugin 模型。

同意你文中绝大部分观点,有尤其是第三点。

不过略有不同看法就是:代码写成啥样,这个主要还是看团队,看负责人;如果团队都不严格要求自己,用啥工具都会乱整的,我见过用 Java 也写成一坨的;总之皆是人为。

所以个人觉得,如果有幸初期进入项目,再忙再累也要吧测试测试覆盖率Style CheckCI 等给弄起来。即使组内都是些训练有素的好手也难免有疏忽、懈怠的时候,更别说后期会有新人进入(说不定招人的时候再一妥协,就。。。)。有了这些,后面 Code Review 的时候,一切皆是对事不对人了,这些辅助工具才是最公正无私的。

我觉得你说的这些跟 rails 无关 而是你接触的编程环境 2 这点更可笑. 谁告诉你 gitlab 没有测试的.

@hging 我想你根本没有认真看,只是一眼掠过,所以不做评论

一言难尽

#5 楼 @jasonliu 我仔细看了,还是和 rails 无关啊

@xlaok 是和 rails 没有关系啊,我只是觉得 rails 目前被普遍的滥用了,被滥用肯定是人的问题,不会是语言或者框架的问题

@qinfanpeng 我也很同意你的说法,项目前期地基要打牢,不然就会是一座危房。

#5 楼 @jasonliu 看差了 但是这个跟 rails 并没有半毛钱关系. 讲道理 语言就是个工具 看的还是人.

没有 code review...... 有 code review,有 测试,每隔一段时间有技术分享,有公司的官方技术 blog,有结对编程。是不是这样的开发团队才是优秀的令人羡慕的开发团队呢

#10 楼 @hging 嘿嘿,被鄙视了吧

#12 楼 @lionzixuanyuan hhhh 最近眼神有问题. 快回来医治我 不过确实跟 rails 没什么关系啊...

@holysoros程序员认真追求极致的态度却不能少 赞一个!

就问题来看, 好像和 rails 毫无关系. 之所以说毫无关系, 是因为每个问题都普遍存在在其他语言和框架以及团队之中, 没有一个是单属于或者集中存在于 ruby/rails 中的.

讲真,Rails 框架可以作为测试驱动开发 TDD 的标杆。如果一个人用 Rails 开发都忽略测试的话,那只能说明他从没听说过什么叫测试。

说跟 Rails 没关系呢,是因为其他语言其他框架也可能有类似问题。说和 Rails 有关系呢,是楼主提的几个点在 Rails 项目里很常见,说明 Rails 太灵活,导致了乱用误用。能力越大责任越大。

#19 楼 @jasonliu 顶楼上。开始学 Rails 的时候也觉得 Rails 非常简单,超级好使,很多功能都可以很轻松地用 Rails 自带的特性实现。但是随着经验的积累,做的 feature 越来越复杂,就越发现 Rails 自身的一些微妙的、不被坑一回根本不知道的细节。面对一种新的语言,新的技术,应该有一定的敬畏之心,特别喜欢这句话。自己的代码写得越多,就越觉得自己懂得越少。

写测试是件很麻烦的事情。。。但很多人觉得很容易。后补测试,成本也很大。

赞一个

你说的这些缺点在 Rails 最开始的岁月简直是 best practice 一样的存在。现在时代变了,Rails 也在不断变化但是也属于 too big to fail。建议尝试一下 grape 作纯后端做一下比较,当然 grape 的代码质量也堪忧。

我觉得 过度依赖或滥用包 这件事情在隔壁 Node 社区真的好严重。确实是一个让人有的时候觉得很麻烦的问题。

#26 楼 @qx 我是感觉 npm 的包比较多。 一个小项目就要 dependencies 很多包。

28楼 已删除
29楼 已删除

按照 rails best practice 来楼主的坑大都还可以避免,个人遇到比较多的是问题是 model 层太肥了,太肥了,太肥了。安利一下破解之法:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

@qx 依赖太多确实也有缺点的。 过度依赖或滥用包

写得很好,看了也有感触。之前做安卓,转 rails 将近三个月了,同样感觉测试是必不可少的。

#20 楼 @hoiyd @jasonliu 赞同 应该有一定的敬畏之心。 在平时工作中同样深有感受:自己的代码写得越多,就越觉得自己懂得越少。

你要是在 MVC 出现前就写过 web app,你就会知道 MVC 还是很好的。你说的都不是 rails 或者 mvc 的问题。你说的问题在软件开发界是普遍存在的

赞一个~~

#14 楼 @holysoros "Ruby 是一门很有魅力的语言,Rails 也是很强大的框架,不过恐怖的是,很多程序员不合规范的使用它。" 这说的太对了。

#40 楼 @academus githuber 想法真不错!

@academus githuber 做得不错

#27 楼 @hxgdzyuyi 而且 node_modules 目录嵌套超多层。这直接导致路径太长。在 Windows 里面就是噩梦。

#44 楼 @academus 注册 githuber 时给我明文发送了默认密码,我希望那不是明文保存的吧?

非常讽刺的,我目前在做的项目有相反的问题。logicless view 与非常 thin 的 controllers,复杂的 models;测试用例过多甚至有重复;code review 流程过于繁琐;不愿依赖 gem 而是宁愿手写徒增负担…… 导致整个开发进度缓慢。

@academus TLS 不來一個?

匿名 #48 · 2016年04月04日

"个人觉得要远离没有 code review 的公司,是否有 code review 并不是某个人或某个团队可以决定的,通常是一家公司的风格,价值观所决定的,如果开发者本身连研发的时间都不能自己评估和决定,还怎么去保证质量呢。" 痛点。。。

@brookzhang 我经历过这样的事情,研发评估开发一项功能需要一个周,但是产品或者运营只给你三天时间,主程和 PM 根本没有话语权,完全由产品或运营主导,他们根本不关心什么 code review,什么测试,只要功能准时上线就好,这种情况太普遍了,我也觉得很无奈。

#47 楼 @steveltn 所谓的开发和程序设计,本来就是一种博弈,博弈在如何取舍复杂和简单之间。大的来说,这是世界上的很多事情也都是博弈,博弈在各种取舍和选择之间。

还有什么更好的替代?

还有什么更好的替代?

感觉只是软件工程思想的转变,并不是 Rails 的问题,事实上 Rails 本来就是为解决一类问题而生。

好文章,有类似体会

感同身受啊!

呵呵,代码写的很烂,但是不敢动,牵一发动全身啊 😄

#50 楼 @jasonliu 标题党,所说的大部分是人的关系不是框架本身的关系。

当维护一个网站比推倒重写一个网站更难 ( 或带来更多郁闷 ),那么 ... 不如推倒重写 ? 至少没埋下的炸弹了。

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