开发原则

更新时间:

Work Design 系列项目作为模块化代码的实践,旨在开箱即用,易于使用。不过业务需求复杂多变,如何能做到以“不变应万变”,需要在开发的过程中分清楚界限:哪些功能是属于模块,是通用的,而哪些功能是属于主项目,是需要在主项目中override 的。

为此,我们在开发工作中提炼了一些开发原则,用于指导我们的工作。

降低学习和使用成本

经过数年的演进,软件开发的门槛越来越低。程序语言,框架,库的繁荣使得开发工作越来越简单。在设计开发库的时候,尽可能降低使用者的学习和使用成本,不仅能使得最终软件成本降低,同时降低了使用者门槛,拓大了使用者群体。

在开发中,有哪些原则能够降低使用者成本呢。

一致性

一致性是减少使用者的理解和使用成本的重要原则,系列engine,主要统一的地方:

  • 统一思路,所有engine基于一致的配置,一致的代码结构;
  • 统一的UI,后台管理界面,基于Semantic-UI;

Stare frame decisis遵循框架先例原则

遵循先例原则是一个法律中的基本原则,即基于现有的认知,确定解决方案。在代码库开发中,尽量遵循语言和框架的风格,遵循现有方法,基于用户已经熟悉和掌握的知识。

  • Ruby风格

尽可能”Ruby Style”, 避免”DSL”,DSL(领域专属语言)的潜台词是小圈子,不一定通用的规则。所以我们在使用Ruby和Rails框架的前提下,尽可能遵循ruby和rails风格的方式,会减少学习和使用成本。

  1. 对于提供的通用模块(一组方法定义),我们尽可能采用Ruby中的 include(prepend)/extend 方式去引用。如果类方法的定义中仅包含对模块的引用,则避免定义类方法,因为类方法会隐藏细节。
1
2
3
4
5
class User < ApplicationRecord
  acts_as_auth # bad
  include RailsAuth::User # better
end

Easy override,便于覆写

没有万能药,一个框架和库不可能满足软件世界的所有需求。如果一个库总想着尽可能去兼容需求,则其复杂度会大幅提升,从而增加用户的使用成本。

所以在设计库的时候,需尽可能为被覆写提供渠道和便利。

作为库的使用者,则尽可能避免直接改动原框架,尤其是对于活跃开发中的库,要相信,origin库(框架)是总能被override 的,只要你对框架和语言足够熟悉。

  1. Rails Engines里的代码可以从各个层面去override;
     * model 层: 无论是include进来的module中的方法,还是重新打开类,定义同名方法即可,区别是include module引入的方法可以通过super去调用,而打开类只是被覆盖;
     * view 层: 以同样的路径覆盖位于engine中的文件即可。
     * controller/routes 层:在routes定义同路径路由覆盖;

最佳实践,避免灵活性带来的额外成本

业务中的需求千变万化,如果想着满足各种需求,会额外增加很多判断。

同时如果一个库很灵活,需要的配置文件也会额外增加。

充分利用生态圈所拥有的能力

Rails作为一个庞大的应用,包含了对于构建系统来说大量实用的功能。在开发的时候,尽量避免重复造轮子。这也是对程序员的基本功的要求。

也许有些需求不足以满足,但是往往可以基于Rails框架进行扩展。

克制

Ruby 是一门非常灵活的语言,提供了诸如打开类(Open Class)等黑魔法。这些元编程往往具有一些副作用。
所以我们应尽量避免直接改原框架,

而是基于(框架)使用回调、钩子等方案。

一处配置,多处使用

很多需要配置的地方,尽量考虑到配置内容可能影响的各个环节。

  • 比如Model层一些属性会用到枚举(ENUM), 如性别包含男和女。这个配置就很适合在翻译文件中来完成。

  • 有些配置可以基于底层的自定义,比如存储某个字段的时候,可能会需要对输入进行 truncate , truncate的大小可以基于数据库scale 文件中的字段limit值来确定。

函数式编程风格的 Helper 模块

函数式

  • Helper 模块,更多层次的应用;