Rails信条

2018/03/29 blog

前言

今天在 Laravel China 社区看优帆远航对 laravel 项目开发规范的时候, summer 在结尾推荐了这篇文章 Rails

在这个互联网如雨后春笋般肆意疯涨的驱使下, 程序员的制造速度也是连绵不绝如滔滔江水。 作为这群大军中的一员, 我不禁想问: 编程, 我们快乐吗?

程序员的幸福最大化

Rails信条的第一条就是程序员的幸福最大化。

早期 Ruby 的极端邪说就是把程序员的幸福度放到第一位。还把追求幸福置于驱动编程语言与生态圈前进的考量之上。

当 Python 对『用一种方法,最好只有一种方法来完成一件事』感到自豪时, Ruby 却喜欢自身表现力与巧妙; 当 Java 正在为保证开发者不犯任何错误而努力时,Ruby 却敢在开发者的工具库中放一个可以用来『上吊』的绳子。 当 Smalltalk 专注于消息传递的纯粹性时,Ruby 却贪婪地累积着关键字和复杂的语法构造。

无论如何,究竟这对 Rails 意味着什么?这个理念为什么持续引导 Rails 演进? 要回答这个问题,我想用另一个启发性的理念来说明,一个早期常用来描述 Ruby 的概念:最小惊讶原则(The Principle of Least Surprise)。 Ruby 应该要如你预期般地运行。可以用下面这个对比于 Python 的例子来解释:

  $ irb
  irb(main):001:0> exit
  $ irb
  irb(main):001:0> quit
    
  $ python
  >>> exit
 
  Use exit() or Ctrl-D (i.e. EOF) to exit
  

Ruby 可以用 exit 和 quit,来回应程序员的需求,也就是想离开终端交互界面。 而 Python 则迂腐地告诉程序员如何做该做的事,即便它已经知道程序员想干嘛了(却只显示错误信息)。这是非常清晰的、微小的、最小惊讶原则的例子。

我认为程序员的幸福除了来自项目完成后的成就感, 也有来自于代码过程中。 如果在修改 bug 的时候能够一击即中, 就不会有不断调试, 却还是返回各种红色的警告字样那种烦躁。 编程语言不只是要严格遵守它的编写规范, 也要有多元化。 我们可以通过自己简单的理解也能够实现功能, 可能它不符合规范, 但是它能得到结果, 这特别是对于刚接触编程的人来说, 有莫大的幸福感。

约定优于配置

有人在乎你的数据库主键命名用什么格式吗?用 id、postID、posts_id 或 pid 真的有差别吗?这真的是值得反复讨论的吗?不!

Rails 的部分使命就是,帮助开发者在日渐复杂庞大的 Web 应用程序决策丛林中劈荆斩棘。几千个无谓的决定只需要做一次,而若是别人帮你做这些决定,那就更好了。

约定优于配置,可以将我们从各种小的决定中解放出来,也提供一个繁茂的草原,让我们孕育更深层的抽象。如果我们可以依赖 Person 类对应到 people 表,我们也可以用同样的词形变化,从 has_many :people 推导出类名是 Person。优良约定的力量是广泛使用才能获得许多好处。

不仅专家的生产力提升了,约定也降低了新手的门槛。Rails 里有非常多的约定,新手无须知道,但却能实实在在地从中获益。他们不需要了解每一件事情为什么是这样,也可以打造出伟大的应用。

假设我是一个新手, 我对某门语言只是简单的认识, 我查看 api 文档发现实现某种功能有好几种方法, 只需要通过不同的配置实现。 但是作为菜鸟的我又怎么知道使用哪种配置能够达到更好的效果呢, 我不得于打开百度, Google 开始搜索实行某某怎样最好? 网上一大堆 说法, 有人赞同 1 , 有人提出了 1 的缺点而支持 2 。 我犹豫不定, 只能靠自己的感觉选择了 1 。

对于项目的开发来说, 很多时候我们都在做着抉择。 如果有一个高手来给你做了决定, 我们按照这个决定完成项目, 我们即做了正确的决定 也了解了为什么这样选择, 这就是约定。 约定不仅方便你快速开发, 还会在协同开发的时候减少不必要的麻烦。 所以我们何必浪费那么多时间 用来做抉择呢?

主厨精选

在餐厅不知道什么好吃该怎么点菜?若你交给主厨挑选,可能可以在了解为何“好”之前,就吃上一顿好菜。这就是 Omakase。 无需成为美食专家或乱点菜碰运气,就可以吃到好东西的方法。

对软件开发来说,主厨精选这个实践的好处是技术栈交给别人帮你组合,跟我们从约定优于配置所得出的论点相似,但它更上一层。 CoC (约定优于配置)考量如何用好单一的工具,而 Omakase 则考量该用什么框架,以及框架之间该如何协作。

开发项目的时候, 如果告诉你框架搭好了, 你或许便能轻松的开发了。

多元化的设计模式

MVC可能在我们的脑海中已经根深蒂固了, 但是不能被 mvc 的开发模式所局限了, 我们允许在 mvc 上加以扩展。 比如 repository , service 。 summer 在 laravel 规范中提到的是不用 repository 模式, 太多封装就成了过度设计 (Over Designed) 。 我的看法是根据自己的具体需求, 如果比较大的项目, 设计比较多的查询代码是可以考虑用 repository 的, 在php中, 当然你可以像 summer 提到的使用 trait 来让我们的 model 看起来不那么臃肿, 其实目的都是一样。 反正在编程的时候, 不要被某种设计模式所局限, 我们为了达到目的可以使用多种方法, 开阔自己的思维。

推崇优美的代码

什么是优美的代码, 至少要让人看上去舒服。 每个人都应该有一套自己的代码规范, 命名规范, 书写规范, 代码的封装。 其实这也是一个码农从新手 到进阶的转变, 如果你现在能够写得一手优美的代码了, 那么再看看自己曾经的代码你就会感受到这点的重要性了。

提供实用工具

许多 Rails 的功能常常饱受这样的争议:“太过自由”。但我现在想到的一个例子是 Concern。这个基于 Ruby 内建功能 Module 之上的一层,薄薄的语法糖。为了单一类打造,可以用来封装多个相关却又独立理解的“关系”(也正是 Concern 名字的由来)。

对于 Concern 的指控是有了一组新的抽屉,让软件工程师很容易把物件都塞进去。这说得没错,Concern 的用途就像这样。

但谬论是不要提供像是 Concern 的功能,但凡让有点能力的人来使用 Concern,便可得出有说服力的概念分离,软件工程师可以从 Concern 获得先天上的架构优势。这么说吧,如果你不能保持 Concern 的整洁度,那你也不可能写出优雅的代码。

尚未学会使用这些实用工具的软件工程师,尝不到收获的果实。这里有一个重要的点:“尚未”。我相信每个软件工程师都有自己的一条道,最终都将变成有能力的 Ruby 与 Rails 软件工程师。有能力我是指足够的知识,知道自己应该在何时,以及该怎么根据实际场景来使用不同的工具,有时甚至使用危险工具。

这不是要把帮助他们成为厉害开发者的责任卸下。框架与语言应该是有耐心的导师,愿意帮助和指导任何人,让他们走上大师之路。同时认可不断犯错是唯一的道路:错用工具、一点教训、汗水,有时候还可能是泪水。是的,想要变强就是应该这样,没有捷径。

Ruby on Rails 是大厨的厨房,是想变成大厨的试炼场。你可能从洗盘子起步,但可以一步步努力往上爬,爬到掌管厨房。别让任何人告诉你,最好的工具不能放心的交给你使用,而是应该看作成长过程的一部分。

重视整合系统

当然有时候这种服务的拆分是必要的。若想建立让大家可以透过 HTTP 实用的 API,好吧,那你就得毫无怨言的处理许多的问题(虽然处理进来的请求比发出去请求要单一,但要是你的服务挂了,别人就会收到错误的状态了)。但这至少对你个人的开发体验伤害有限。

更糟糕的是,当系统过早解耦,或是过早拆成小服务,以及更糟糕地拆成 Microservices。这是现代网络应用的错误认知,你只会反复地重造系统:同样的功能在后端做一次,在前端再做一次,在 Native 手机端又再次实现一次等等。这不是自然规律,你也不需要这样。

若想在整个应用里共享大部分的功能,这完全是可行的。桌面应用和 Mobile App 可以用同样的 Controller 和 View。尽可能地把功能集中在 Majestic Monolith - 整合系统。集中在一起完全不需要牺牲构建速度,开发者体验,以及其它错让你以为要尽早拆分系统的因素。

这正是我们要追求的系统:包含所有功能,容易发布,简单理解的单一系统,整合系统。

进步比稳定重要

当一个系统已经存在超过 10 年,比如 Rails,自然会慢慢僵化。每一处的修改,都有百万种理由可能会变成别人的困扰,或是有人仍需要旧的行为。这对他们来说都是合理的理由。

但若我们太仔细听取保守派的意见,我们将永远不知道另一边的声音是什么。我们需要勇敢地做出改变,打破陈规,然后才可以茁壮演化。正是这样的演变,才让 Rails 存活下来,并可能继续繁荣发展(数)十年。

作为一个从其他行业转型的码农, 深切体会到互联网的更新换代之快。 也许你还停留在 2.0, 3.0 , 甚至 6.0 都发布了。 不要停下自己的脚步, 要马不停蹄的学习, 既然它要升级肯定有它的道理, 优势, 这也是技术上的提升。 我们在学习新知识的同时, 也是增加眼界, 了解世界。

包容并重

包容并重并不代表把所有东西强加给所有人。这只是代表你欢迎人们带自己的饮料来参加你的 Party。我们要给别人加入我们的机会,却又不能失了我们的灵魂与价值观。因为我们从他们身上可以学到如何调一两杯新的饮料。

当然这是要付出代价的,需要努力让付出的贡献受欢迎。特别是我们目标不仅仅是要吸引住已经在社区的人,我们永远都要真正考虑如何降低起步门槛。

你永远不知道,改正文件错误拼写的人,可能就是下个大功能改进的黑马。无论是多小的贡献,都能笑着说感谢,这样贡献者就能一直持续下去。

虽然我们认为做的很对, 但是我们也不介意接受别人的批评。 只有敢于接受不同的声音, 才会进步, 而不局限于个人的思维。 开源精神!

Search

    Table of Contents