TL;DR

这篇文章来自于 Ruby China 上一个很有意思的 讨论 。原文是一篇国外开发者的吐槽 Rails Hurts 。你看的没错,他还特意注册了一个域名 :)

看完后我觉得作者有些断章取义和偷换概念,因此有了这篇文章。主要是想探讨一下,Rails 真的 Hurts 吗?下面我们根据原文的结构一条一条来分析(吐槽)。

看这篇文章之前,我建议看看作者的原文。不管是否赞同他的想法,都会有些收获。

DRY - Don't repeat yourself

DRY 只是一种被推崇的原则,但不代表必须无时无刻的严格执行。作者把它理解成 “无论什么时候 你看到一个重复的概念,你都 应该马上 去把它抽象成一个方法或类” 太狭隘和绝对了。我们老祖宗也说过 “事不过三”,生活中估计也没人能严格做到这一点。

关于代码重复和耦合的问题,作者的论据显然来自 Sandi Metz 说的 “重复比错误的抽象要廉价的多”,但这其实不是 DRY 的问题,而是错误的抽象的问题。而错误的抽象往往来自于对一些概念缺乏全局理解。拿构建领域模型举例,对一个概念的完全理解往往需要反复不断的尝试和探索,这是需要花时间的,而不是了解了一点概念就 应该马上 去设计的。所以我想应该是作者对 DRY 的片面理解和执行导致了错误的抽象,从而认为 DRY 会导致代码耦合。其实这两者一点关系都没有。

KISS - Keep it simple, and stupid

这个其实是吐槽 AR 而不是吐槽 KISS 的。关于 KISS 各人有各人的理解。作者把 KISS 跟 AR 联系在一起是因为 AR 是 用简单的接口隐藏复杂的实现 。其实更应该吐槽的是 AR 混合了太多的关注点,与这点有关联的原则应该是 Single Responsibility Principle 。我也觉得 AR 操心的事情太多了,它的设计在现在来看已经过于复杂了。正因为功能强大,才导致了之后 Fat model 这种理念的兴起。

最后我还是比较赞同这句的:Rails is not simple, it is convenient 。

Conventions over Configurations

我一直觉得一个 Convention 好不好得取决于两点,一是大众对这个 Convention 的接受程度,二是这个 Convention 符不符合直觉思考。Rails 在这两点上做的都没问题。作者主要吐槽的是 Rails 提出的 CoC 理念把很多第三方开发者都影响了,让他们制造了很多诡异的 Conventions 和滥用元编程写 DSL 。但这仍然不是 Rails 的问题,也不能证明 CoC 是不好的。

是否 CoC 从广义上看是 implicit 和 explicit 孰优孰劣的问题。我觉得把符合直觉的配置变成 Conventions 能简化很多事情,其他部分不妨用 Configurations 。

Fat model, skinny controller

这确实不是个好事。但 Rails 社区也早就不这么干了,现在几乎找不到 Fat model 的文章了,反 Fat model 的文章倒是不少。

说到 Fat model 这个话题,我抛一个不成熟的观点,我觉得 Rails 对开发的简化很大程度上来自于 对抽象层级的压缩 。这点在 AR 上体现得尤其明显。这种设计在做简单的功能时会非常省事,在 model 里写几行 validation 和 callback 就把数据库事务,表单验证,业务逻辑前后的副作用(比如发送邮件)全部搞定了。但如果复杂的场景下还沿用这种开发方式就会导致 model 臃肿,业务逻辑互相缠绕等问题。究其原因,还是抽象层次的压缩导致了代码缠成一团。

但从另一个角度看,Rails 也并没有阻止开发者去加自己的抽象层。validation 和 callback 这些功能也被设计成很容易加到其他 class 里面。所以 Rails 还是蛮灵活的。只是开发者必须意识到对简单问题的处理思路(很多人理解的 Rails way)基本不可能沿用到复杂问题领域,而这点认识往往是在被坑过之后才知道的。

Rails is not your application

这部分提到的业务逻辑和 Rails 框架混杂,本质上还是没有对业务逻辑做足够的抽象,或者说对 OO 缺乏足够的理解才导致把 Rails 当做英语考试的完形填空去做。但现实中的业务逻辑是千变万化的,没有一个框架能完美地抽象出公共的模式。

其实一个引申的问题更值得思考,那就是框架到底应不应该提供架构决策?我目前的想法是框架也是系统架构的一部分,但不能完全代表整个系统的设计。这个话题也许会让人联想到 Domain-Driven Design 和 Uncle Bob 说的 Hexagonal Architecture ,或者 DCI 等模式。有任何想法欢迎探讨。

YAGNI - You aren't gonna need it

这一段的论点是 Rails 默认给你了太多的东西,但这就是所有全栈框架的思路,拿这点吐槽 Rails 也是不客观的。关于全栈框架和微框架的讨论已经很多了,就不多说了。

Prefer composition over inheritance

Ruby 的 mixin 到底算不算 composition 这点真不好说。我赞同作者文章下面的评论说的,这是 composition 本身定义太模糊了。Sandi Metz 在 Practical Object-Oriented Design in Ruby 里定义的概念更清晰:

I think maybe what we're getting at here is "composition at the object graph level" rather than "composition at the object level"

总结

作为一个干了 8 年的开发者,这些年也用过不少框架。我发现但凡红极一时的框架或类库,都有这么两个特性:

  • 优点足够明显,能在当时的世界引发一些新的思考,指引一些新的方向。

  • 并非完美无缺,只是缺点都能通过一些方法来解决或绕过,换句话说,没有无法解决的致命缺陷。

Rails ,AngularJS ,React 莫不如此。Rails 是有一些设计缺陷甚至架构上的误导,但也确实带来了一批新的理念,也许现在看起来都是老生常谈,但在 07 年那个时候却是一种颠覆。

另外,再先进的框架也无法取代架构设计,开发者仍然应该学习一些设计能力和原则,虽然有时候它们跟框架理念会有冲突,但更多是互补的。

So, does Rails hurt? 看到这里,我想你自己心里应该有了答案。

Does Rails Hurt?相关推荐

  1. 诗歌rails之如何写一个简单的Rails Plugin

    生成plugin骨架代码: Ruby代码 ruby script\generate plugin MyPlugin ruby script\generate plugin MyPlugin 功能需求: ...

  2. 我的Rails笔记(1)

    <Agile Web Development With Rails>Notebook. 环境: Rails 3.1.0 Gem 1.8.10 Ruby ruby 1.9.2p180 1. ...

  3. [rails] 我的订餐系统 -- 小试ruby on rails(转)

    前言         近期在java社区中一种新的脚本语言ruby,及用ruby开发的一个wab框架 rails也热闹了起来.引起了不少的java开发人员的关注. 本人平时还是很少接触脚本语言方面东东 ...

  4. rails 添加外键_如何在Rails后端中添加功能强大的搜索引擎

    rails 添加外键 by Domenico Angilletta 通过多梅尼科·安吉列塔(Domenico Angilletta) In my experience as a Ruby on Rai ...

  5. ruby on rails_我成为了Ruby on Rails和React的贡献者,你也可以

    ruby on rails I am really grateful to have contributed to a few open source projects, including two ...

  6. 新手安装ruby on rails(ror)的成功必备手册

    2019独角兽企业重金招聘Python工程师标准>>> 如何快速正确的安装 Ruby, Rails 运行环境 每一位使用windows系统来进行ROR开发项目的都是这个世界上折翼的天 ...

  7. rails应用ajax之二:使用rails自身支持

    考虑另一种情况: 1. 页面上半部分显示当前的所有用户,页面下半部分是输入新用户的界面: 2. 每当输入新用户时,页面上半部分会动态更新新加用户的内容: 我们还是用ajax实现,不过这次用rails内 ...

  8. 例题6-2 铁轨(Rails, ACM/ICPC CERC 1997, UVa 514)

    栈应用 例题6-2 铁轨(Rails, ACM/ICPC CERC 1997, UVa 514) 错解 1.每次要把栈清空 2.不能用空的栈(栈顶)去比较 #include<iostream&g ...

  9. nginx rails 详细站点配置入门教程

    Ruby on Rails 是一个用于开发数据库驱动的网络应用程序的完整框架.Rails基于MVC(模型- 视图- 控制器)设计模式.从视图中的Ajax应用,到控制器中的访问请求和反馈,到封装数据库的 ...

最新文章

  1. java监控多个线程的实现
  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(4)-创建项目解决方案
  3. c面试题总结(含答案)
  4. 怎样理解js数组中indexOf()的用法与lastIndexOf
  5. python下常用OpenCV代码
  6. 的环境下 qt 运行在_Ubuntu16.04环境下运行vins mono(环境配置及编译)之ROS kinetic的安装...
  7. php安装文件怎么打开文件_我的php文件怎么打开_如何打开php文件的办法
  8. 学web前端好找工作吗?想给初学者们几点建议
  9. HTML 去调table表单里面td之间的间距
  10. Python实现批量处理扫描特定目录
  11. 【狂神说Redis】总集篇
  12. Google Chrome谷歌浏览器去掉右上角更新提示图标
  13. 《单片机原理及应用(魏洪磊)》第六章第11题
  14. 抓包神器 Charles
  15. kermit使用总结
  16. a后缀名是什么格式文件,怎么打开.a文件
  17. 人脸检测通用评价标准
  18. 单臂路由的详解及简单配置
  19. [游戏商业化]一些基础概念点,做个记录
  20. 超级表格上线消息提醒功能了~

热门文章

  1. python 配置文件介绍
  2. python3程序运行中会跳过注释行,Python: 读取文件时如何忽略#条注释行
  3. lnmp 备份mysql_mysql全量备份与增量备份
  4. android 报500是啥异常_一文领会Android消息系统的Message设计
  5. Linux保护文件实现,Linux完整性保护机制模块实现分析(1)
  6. 实现自己的类加载时 重写方法loadClass与findClass的区别
  7. 什么是事件?JS中都有哪些事件?
  8. mv命令移动文件到指定目录
  9. 大数据学习笔记15:MR案例——IP地址去重
  10. PHP案例:单引号字符串与双引号字符串有什么区别?