从 12 年毕业到现在,前前后后经历了 2 个 rails 项目,从机缘巧合接触 ruby,到专职从事 rails 开发,再到暂时告别 rails,我有太多的感触。我见过有人把 rails 视作神兵利器,也见过有人将其视作花拳绣腿,而我从来不愿意参与这些口舌之争,我只觉得写 rails 挺开心,这就足够了。但是悲催的是,我所经历的 rails 项目,都让我觉得非常郁闷!
都说幸福的人都一样,不幸的人各有各的不幸!但是不幸的 rails 代码大多数都是相同的。
Rails 采用了 MVC 的架构:
rails 社区一直推荐 fat model, thin controller (也有人持不同意见)。与数据库查询和业务逻辑相关的均会放在 model 层,视图层根据请求的参数选择合适的模型并向视图层返回数据,而视图层只根据接受的数据渲染页面。但我见过很多人把业务逻辑放在 controller,动不动就是几百行代码,视图层还掺杂着数据库操作,erb 模版已经够混乱了,再加上各种 where, find_by...... 欲哭无泪啊!而这还不是问题的关键,关键是 Fat View, Fat Controller 会导致代码难以测试(咋们就不追求啥 BDD 了,有这个问题的基本上都不会有测试)。视图层的代码会根据请求参数的不同输出不同的结果,本身测试就很麻烦,如果再掺杂业务逻辑(数据库操作,异步任务,第三方接口调用等),测试复杂度急剧上升,所以很多的开源项目都会放弃控制层的测试,前提是控制层的代码简单的不需要测试,因为它本身就是处理请求的,不是处理业务的。
如果有前面的不幸,这个不幸必然发生。曾经有位技术总监面试我的时候跟我说:“我看你以前有持续集成相关的工作经验,我希望你加入公司以后,可以帮助项目搭建一套 CI 系统...... ”当我从 gitlab 克隆下代码,翻开 rspec 目录一看——空空如也!心中直呼:臣妾做不到啊!!!
可以弥补测试用例的前提是:
其实没有测试用例的最大痛苦在于,明明代码写的很烂,你却不敢动!!!
个人觉得要远离没有 code review 的公司,是否有 code review 并不是某个人或某个团队可以决定的,通常是一家公司的风格,价值观所决定的,如果开发者本身连研发的时间都不能自己评估和决定,还怎么去保证质量呢。ruby 本身做为一门动态语言,自由度灵活度都很高,我见过把 ruby 写的像 C 语言一样的。如果你待的 ruby 团队没有 code review,建议你早点离职,因为最后离职的人总是最痛苦的,他要接下所有人留下的烂摊子。
gem 包的好处显而易见,它可以极大的加快你的开发进程。登录认证用 Devise,权限管理 Cancancan,样式用 Bootstrap,部署用 Capistrano...... 在开发一个功能的时候,你首先会想是否有现成的 gem 包实现这个功能。这很正常,我也是这样,不去重复去发明轮子。但是在用一个 gem 之前,至少要看几个指标:
有人会说,我的 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 之旅的伙伴有所帮助!
写得很不错!👍
真的非常有感触,尽管学习 ruby 的时间不长,但你提到的四点基本上都遇到了。
坦白来讲,我认为这并非是 rails 本身导致的,其他语言多少也有类似的现象,这跟企业文化跟个人精神意志都很有关系。
如果一个企业是因为 rails 开发东西快而选择它,那背后折射出的可能就是急公好义的信号,它的价值观并不在于追求对产品质量和服务上的深耕细作,而是为了尽快拿到风投、抢占先机等,我们不能否认在中国市场这种厮杀背后的无奈,只有不忘初心坚持下来的人方得始终;拿了投资忘了初心的人极有可能成为泡沫的始作俑者。我相信这里没有一个老板愿意承认自己属于后者,所有人都在努力的向着某个目标逼近。
个人层面来说,身处这个时代,作为一名依靠技术谋生的人,是否也会时常检查一下自己的初心。《项塔兰》一书里提到了一种被称为「博尔萨利诺帽」的测验,博尔萨利诺帽是一种非常名贵的帽子,黑帮老大都将它视为珍宝,而这个测验被用来测试这顶帽子的真伪,方法是把帽子卷成一根圆柱,然后找一枚戒指穿过,再展开时如果帽子没有褶皱,与原来一样就是真的。
其实我们无时无刻不在做着博尔萨利诺帽测验,不论我们面对是一个新项目还是老项目,不论我们是要做重构还是写测试,我们是否承认起初都曾想过它终将呈现出来的样子、我们是否承认用我们曾希望用心目中最完美的方法去解决它的过程,甚至我们是否承认我们都乐于利用已知的技术去最大化地实现自我价值,这些不都是在经历穿越戒指的考验么,当你穿过戒指后仍然还有那份完美的心态,那份坚毅的执着,应该收获的是满满的成就,又怎么会写出越写越糟的代码,越描越黑的框架,越来越多的不幸呢,唯一能说明的就是有许多人并没有通过博尔萨利诺帽测验,他们在经历痛苦的时候留下了折痕。
以上说的不一定对,纯属有感而发 ~ :)
同意你文中绝大部分观点,有尤其是第三点。
不过略有不同看法就是:代码写成啥样,这个主要还是看团队,看负责人;如果团队都不严格要求自己,用啥工具都会乱整的,我见过用 Java 也写成一坨的;总之皆是人为。
所以个人觉得,如果有幸初期进入项目,再忙再累也要吧测试、测试覆盖率、Style Check、CI 等给弄起来。即使组内都是些训练有素的好手也难免有疏忽、懈怠的时候,更别说后期会有新人进入(说不定招人的时候再一妥协,就。。。)。有了这些,后面 Code Review
的时候,一切皆是对事不对人了,这些辅助工具才是最公正无私的。
没有 code review...... 有 code review,有 测试,每隔一段时间有技术分享,有公司的官方技术 blog,有结对编程。是不是这样的开发团队才是优秀的令人羡慕的开发团队呢
Linux 创始人 Linus Torvalds 曾说过“C++ 是一门恐怖的语言,令它更加恐怖的是,许多不合规范的程序员使用它……”。Ruby 是一门很有魅力的语言,Rails 也是很强大的框架,不过恐怖的是,很多程序员不合规范的使用它。
之前写其他语言的时候会很小心谨慎,大家也会反复思考:这样写会不会多用内存、会不会有内存泄露、会不会有多线程竞争关系,这是语言强加给程序员的价值观(当然也跟公司环境有关)。幸运的是 Ruby 没有这种限制,但是程序员认真追求极致的态度却不能少。
就问题来看,好像和 rails 毫无关系。之所以说毫无关系,是因为每个问题都普遍存在在其他语言和框架以及团队之中,没有一个是单属于或者集中存在于 ruby/rails 中的。
讲真,Rails 框架可以作为测试驱动开发 TDD 的标杆。如果一个人用 Rails 开发都忽略测试的话,那只能说明他从没听说过什么叫测试。
说跟 Rails 没关系呢,是因为其他语言其他框架也可能有类似问题。说和 Rails 有关系呢,是楼主提的几个点在 Rails 项目里很常见,说明 Rails 太灵活,导致了乱用误用。能力越大责任越大。
现在很普遍的一个现象就是很多人都觉得 Rails 太简单的,简单的在开发组里随便找个张三李四就可以开项目了,连 rails guide 主要章节都没看过就开整了,更别说什么规范,最佳实践了。等项目做了几个月,代码已经几万行了,应用已经跑起来了,公司所有人都在为他们的开发速度所惊叹,对他们的能力大加赞赏!却不知道这是个定时炸弹,如果很不幸你成为了接盘侠,你也只有有苦说不出。我并没有贬低任何人的意思,只是觉得在面对一种新的语言,新的技术,应该有一定的敬畏之心,愿意花一点功夫去做功课,这样对自己,对别人都是有好处的。
你说的这些缺点在 Rails 最开始的岁月简直是 best practice 一样的存在。现在时代变了,Rails 也在不断变化但是也属于 too big to fail。建议尝试一下 grape 作纯后端做一下比较,当然 grape 的代码质量也堪忧。
按照 rails best practice 来楼主的坑大都还可以避免,个人遇到比较多的是问题是 model 层太肥了,太肥了,太肥了。安利一下破解之法:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
你要是在 MVC 出现前就写过 web app,你就会知道 MVC 还是很好的。你说的都不是 rails 或者 mvc 的问题。你说的问题在软件开发界是普遍存在的
#14 楼 @holysoros "Ruby 是一门很有魅力的语言,Rails 也是很强大的框架,不过恐怖的是,很多程序员不合规范的使用它。" 这说的太对了。
我用 Ruby 五年多了,Rails 是我最开始学习 Ruby 的理由,但我今天几乎不再开发 Rails 程序——我并不是说 Rails 没有用,或者 Ruby 不好,主要是因为 Rails 应用复杂度太高——虽然 Rails 功能丰富,但不都是我想要的,额外的功能引入的代码增加不必要的复杂度、降低了效率。
然而我今天还在用 Ruby 做 Web 开发,只是切换到了 Sinatra——它足够轻快、本身代码只有几千行,而且也是基于 Rack 的,这意味着它可以运行在一切 Rails 可以运行的环境下。同时,我并没有完全放弃 Rails——Rails 的主要组件,如 ActiveRecord 和 ActiveSupport 都是可以独立使用的。我也经常在我的 Sinatra 应用里引用它们——我觉得其实这是 Rails 乃至整个 Ruby 社区一个非常好的地方:那就是软件的可复用程度非常高,这得益于 Gems 体系,和 Rack 架构,当然还有 Rails 的良好设计。作为一个 Sinatra + ActiveSupport + MongoDB 的例子(广告):
对 Web 开发新手来说,我不建议从 Rails 开始,因为 Rails 实在是一门“易学难精”的框架,Rails Guide 很好,但如果天真的以为 Web 开发用 Rails 会那么简单,那么你就要用接下来的一年甚至更长的时间明白一个道理:这世上没有捷径、没有“银弹”,有的只是脚踏实地把所有的问题都搞清楚,不要妄想一个框架能给你什么你自身不具有的超能力。如果你对 Ruby Web 开发感兴趣,你应该从 Rack 开始,搞清楚 Rack 的原理,然后试试 Sinatra,如果你的业务需求真的复杂到必须用 Rails 不可,那么用它——在你搞清楚了 Rack、HTTP 和 RESTful 之后——这时你应该已经不是一个新手了。
我也建议创业公司或者小型机构:如果你们没有一个所谓 Rails 专家,就不要轻易尝试用 Rails 做产品开发,结果只能是陷入泥潭不能自拔。
楼主的经验和意见,我基本都赞同。我还想补充一点:要用好 Rails,你还得补补英文——要想在第一时间找到解决问题的办法,或者参考别人的、更多的 Rails 实践经验,国外的网站、社区是必不可少的。国内的 Ruby-China 也不错,可惜人气还是稍逊,毕竟国内 Ruby 程序员只算小众。
非常讽刺的,我目前在做的项目有相反的问题。logicless view 与非常 thin 的 controllers,复杂的 models;测试用例过多甚至有重复;code review 流程过于繁琐;不愿依赖 gem 而是宁愿手写徒增负担…… 导致整个开发进度缓慢。
"个人觉得要远离没有 code review 的公司,是否有 code review 并不是某个人或某个团队可以决定的,通常是一家公司的风格,价值观所决定的,如果开发者本身连研发的时间都不能自己评估和决定,还怎么去保证质量呢。" 痛点。。。
@brookzhang 我经历过这样的事情,研发评估开发一项功能需要一个周,但是产品或者运营只给你三天时间,主程和 PM 根本没有话语权,完全由产品或运营主导,他们根本不关心什么 code review,什么测试,只要功能准时上线就好,这种情况太普遍了,我也觉得很无奈。