Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Refactoring lesson : from GPA 1.4 to GPA 3.0

Yi-Ting Cheng
September 24, 2016

Refactoring lesson : from GPA 1.4 to GPA 3.0

RubyConf China 2016 - Xdite

Yi-Ting Cheng

September 24, 2016
Tweet

More Decks by Yi-Ting Cheng

Other Decks in Technology

Transcript

  1. 全栈营教头 • Ruby on Rails • Agile • Growth Hack

    • 认知⼼心理学 + 技术教学 https://ruby-china.org/topics/31080 無編程經驗的新⼿手,如何在四周開發實戰等級產品
  2. 3.0

  3. 1.4

  4. 2014 年 7 ⽉月 • 矽⾕谷 O2O 送餐公司 • 种⼦子轮

    拿了 250 万美⾦金 • A 轮拿了 1100 万美⾦金 • 来台湾征才 • 8 ⼈人公司加⼊入了 SpoonRocket • 公司⼤大举招⼈人
  5. • Angular - 客⼾戶 Web 端 • Android • iOS

    • Rails - Admin • jQuery - Dispathcher (⼈人⼯工配餐台)
  6. • 虽然技术团队 20 ⼈人 • 每天可以拉上超过 20 ⽀支 pull-request •

    但是每天只能 deploy 2 ⽀支 pull-request • 凌晨 3:00 (台湾时间)开店,SA 只能睡公司....
  7. • 经常性 Rollback • 20 ⼈人还是只有 2 ⼈人战⼒力 • 每天开店⽼老是炸

    • ⽆无法做促销,呼叫⼀一只菜单 API ~= 700ms • 开启 Admin Controller 超过 60 秒
  8. • 刚加⼊入没多久就后悔 • Grape API • 每⼀一只 Grape API 约

    1000-2000 ⾏行 • 毫⽆无逻辑的 EndPoint • 重复逻辑到处复制贴上 • Admin 后台的单⼀一 index action 也⾼高达数千⾏行
  9. • CTO 与第⼀一个 RD。凭借蛮⼒力硬是上线 • 永远保持能卖东⻄西就好 • 我⻅见识到的是 GPA 1.0

    的代码也能募到这么多钱.... • 所以代码是否干净与能不能赚钱没有关系
  10. 結果 • API 代码 95 % 以上覆盖 • 上了 CI

    • 全代码覆盖率 60% • GPA 3.0
  11. • 快 100 只 API • 50 只以上 Controller •

    快 70 个 model • 10000 多⾏行代码
  12. WIKI 上必须要有主要 API 的⽂文档 • GET / POST • 输⼊入参数

    / 输出结果 • 回传值 • (真实资料)
  13. 实作步骤 • 半强迫每个 RD,⼀一个礼拜必须写 10 ⽀支测试 • 没时间也⾄至少做到 • API

    200 • 验证格式正确 • ⼿手头掰不出测试资料就使⽤用「真实资料」
  14. • 牵涉到 3rd Party 的 API 不写 Test • 呼叫演算法的

    API 不写 Test 
 
 
 
 
 
 • 因为代码太渣了,⽆无法强⾏行 mock…
  15. • ⼀一个礼拜补完所有 API Test …(⾄至少有 200 与格式) • ⾄至少 RD

    要是拉 pull request,没有绿灯就可以叫他滚 回去了 • 快速滤掉第⼀一层低级错误 • rollback 率⼤大幅下降
  16. 从 API 分离下⼿手 • Before : ⼀一⽀支 API 档案 >

    1000 ⾏行代码 • After :⼀一⽀支 APP 的「档案」必须⼩小于 160 ⾏行
  17. 闪坑 • 不会再被 if / else 坑到 • 不会再也不知道⾃自⼰己再改那个 end

    point 的代码 • 有机会把「相近」的 Resource 放在同⼀一个档案 • 因为有 200 Test 可以放⼼心的搬家
  18. • Step 1: 先估计「⼯工作量」 • Step 2: 装上红绿灯,⾄至少保证永远有基础绿灯。 • Step

    3: 切细变成可以「重构」的区块 • Step 4: 盒⼦子打包法,补⿊黑盒⼦子测试
  19. CodeClimate Refactor 法 • 找出 F 等级代码。 • 专攻重复区域,打包成 method,补

    unit test。 • ⼜又补了⾄至少 > 50 个 Test • 重复的代码 = 重要的业务逻辑(到处都⽤用到)
  20. • ServiceObject (商业流程) • Calculator ( 计费可以随时抽换不同公式 ) • Validator

    ( ⼀一个 Order ⾄至少要经过 10 道验证,把验证做到可叠 加 ) • Serializer ( 原先是 Hash,改⽤用 Serializer 好管理 ) • Cells ( 让 View 可重复使⽤用 ) • StrategyClass ( 可策略抽换应付「营销活动」与「价格模型」 ) • Worker ( 把效能瓶颈移到背景去执⾏行 ) • Concern ( 复合使⽤用把常⻅见⼯工具类 method )
  21. ServiceObject • 查价 / 库存 • 下单 • 退单 •

    跟踪订单 • 计算运送所需时间 • 不同版本 API,使⽤用不同 ServiceObject
  22. • 2 pull request => 5 => 10 • 终于可以上

    CI server • 不是绿灯,pull request 不会有⼈人理
  23. • ⼀一个 Controller ⼏几千⾏行代码
 
 
 • ⽼老板把逻辑都写在 JavaScript ⾥里⾯面

    • 因为 Dispatcher 台是 JavaScript 写的 • 只好其他业务逻辑也⽤用同样的⽅方式
  24. 第⼀一步 • 把 Dispatcher 「以外」的部分搬去 Rails CRUD • 不太需要写 Test

    • 烂了请美国同事 hotfix,也不影响消费者下单 • 拆了 ~15 ⽀支 Controller
  25. 第⼆二步 • 把 Dispatcher 当作是 Client • 不再是 Rails 与

    JavaScript 混合产⽣生 View • 显⽰示逻辑都使⽤用 JavaScript • Rails 作为 API 提供资料 • 补 API Test
  26. • Frontend 组搞了很久 • 巨坑.... • 那时候剛有 React, … •

    学到以后复杂逻辑绝对別⽤用 jQuery 先搞。
  27. 经过这⼀一轮 • 1 个⽉月就从 1.4 => 2.95 • 代码覆盖率到 40%

    + • 花了另外的 5 个⽉月 2.95 => 3.06 • 花了另外的 5 个⽉月代码覆盖率到 60% • ⾜足够好
  28. • 每天 Release 15 ⽀支 pull request • db migration

    或是改资料,还是个坑,需要⼈人为介⼊入 • 运营团队抱怨虽然没有 500,但是业务逻辑⼀一直在变 • 应该要出 Release ⽇日报
  29. • ⾃自动汇集 pull request 成 deploy ⽇日报 • 必须叙述作⽤用 •

    若有 migration 必须在 #Risk 环节注记 • Deploy ⾃自动执⾏行
  30. 成果 • GPA 3.06 • 60 % test coverage •

    15 pull request/day • API has ~95% test coverage. • major API response time < 80 ms • We shipped 6-8 major features every week.
  31. Take away • 先搞清楚有多少测试要写。 (否则会遭到公司否决) • 先写 Integration Test •

    Integration test -> Service Object test -> Unit test • 尽量提供 developer 「动机」去写 • 测试资料 • 可复制的测试代码
  32. Take away • 做 Refactor 前⼀一定要先上 Test • 前期⺫⽬目标是「有动机去做」 •

    中期⺫⽬目标是「接⼝口干净」 • 远期⺫⽬目标是「⾃自动部署」
  33. • 虽然「补测试」这么不爽 • 之后创业我还是不会先写测试 • 因为我理解了 GPA 1.0 还是可以拿到 1100

    万美⾦金 • 商业的重点是「测试」你的 「idea」,⽽而不是「代码」 • 赚了钱你要雇⼏几个⼤大⽜牛来帮你重构都⾏行