提效就是减少浪费吗?
基于现状的各环节浪费进行分析,避免浪费,就能达到提效的目的了么?这么说未必正确,要看目的是什么。有三种可能的目的:
- 减少总花费:可能人变少了,但是要开发的时间变长了。
- 提高总吞吐:通过堆更多的人,再等同的开发时间里,交付了更多的业务价值
- 降低延迟:通过堆更多更多的人,不在乎有多少D U [ G w j \ x F浪费,只要能快速响应市场就可以
不同语境下说提效,其目的可能是不同的。比如对于前段时间很火的买菜业务,大家不约而同选择的是堆更多更多的人,以降低延迟为目的,不在乎投入的方式来搞。如果为了省几个P5的工资,导致上线开城延迟了一个月,丢掉了市场,那就不值得了。
即便说提效的时候,指的就是消除浪费。如上图所示,我标记_ % t了6个可能产生浪费的环节。下面逐个来说每个环节产生的浪费,存在了这么长的时间都是有道? J B 3 $ J u c B理的,都没有那么容易被“提效”。不是说每一条路都走不通,而是说不N 3 z 9 0 {存在什么低垂的果实,都有坑。
1、产品经理/UI设计师与开发者之间的交接浪费
很多人都看到了产品经理W f t 7 E 6 A e要写一遍 PRD 稿,然后开发者照着翻译一遍。UI 设计师要画 UI 稿,然后前端开发要照着还原 UI。如果能够减少这个交接环节产生的浪费,让 PRD 稿,UI 稿能直接进入下一个环节,岂不美哉。
这条路走下去的坑可能是什么?PRD 稿和 UI 稿存在的意义在于减少返工。如果没有前一道工序,让客户一句话需求直接对接开发。那很有可能做出来了,就不是客户想要的。这个时候要去改代码,比修改 PRD 稿和 UI 稿的代价要大多了。所以 PRD 稿和 UI 稿的优点就是改起来快,没有可运行的代码那么多要求,可以很随意。如果要求 PRD 稿和 UI 稿能够直接翻译执行,那势必要添加语法和语义规则限制。这可能会损害“低成本可修改可讨论”这个c { 6优点,产品经理和 UI 设计师要花更多的时间来让产出物符合规范上,而不是花更多的时间和客户讨论反复修改上。
2、开源的库和框架提供的可复用代码太少了,做过很多中后台项目,仍然有大量重复的代码
这个浪费* M # $ ` # # f是说,开发者复用的库和框架都是非常底层非常基础的数据结构,RPC通信这些东西。做了个几个项目之后,就会得出自己是 CRUD boy 的想法,觉得总这么重复下去不是办法。如果能够搞出几个开源的库和框架,那岂不是造福人类?
这条路走下去的坑可能是什么?开发者是无法反向约束客户需N b D + f O求的。任意两个客户,即便就是 CRUD 也会有不同的细微差别。比如 list /W i o & u g j H detail 是上下,x A p w s 1还是左右,还是弹框,还是跳页?列表是分页还是无限下拉,是有筛选,还是有搜索?开源库之所以都是那些基础的东西,就是因为那些东西共性大。稍微往靠近用户的一侧靠一些,花样就百出。
然后第二a ` ) 2 n g a个可能的想法是满足 80% 的需求,那剩N K 0 * y S = D #下的 20% 让开发者去传参数,传 callback,写 patch,写 DSL 来满足。之前那些开源库的作者没有做到这一点,是因为他们笨(划掉),是因为我有更牛x的代码生成/组件插件技术/xxx
这条路走M 8 ~ R M下去的坑可能是什F m { | J N I k么?不讨论是不4 i X ?是有什么牛 x 的技术就能大幅改进在已有代码上做定制的体验,我个人经验是不存在这样的技术,不管运行时的还是编译期的,能力上都基本上等价。即便有这样的技术,H = @ \ 9一方面写 20% 的人至少要知道 80% 是哪 80%,I d O他需要知道已有的库和框架提供了什么,需求是什么,然后 diff 出 20% 的部分。然后还要知道在这个指定的库和框架上怎么写那 20%,7 k l @ I P没有两个框架提供的扩展方式是一样的,都有自己独特的搞法。
上世纪80年代的时候,流行组件市场的传说。写好业务组件,然后拿出去卖钱。但是从历史来看,最终组件市场的形态是 github 这个最大同性交友社区。最佳的代码复用方式是拿来主义,直接 fork 一份,在别人的代码基础上做修改。啥参数化,插件化,callback,都没有直接改源代码来得直接,好用。
3、现有的代码认知负担太大,新人要很长时] b o j m间才能接手。反馈周期很长,没法快速修改快z , Y , } Z X Z f速迭代。; 0 ( c G i ~ & )
观察人是如何阅读代码修改代码的,不难得出这两个主要浪费的点。
- 认知负担
- 反c p @ w \ , 7 Q馈周期
认知负担:代码读起来很复杂,不好理解。一份代码要交接给另外一个人来写,他要很长时间才* } U C a P c !能达到Y K 9 \你之前的水平。甚至按照 Programming as Theory Building 的观点,没有人可以达到作者一样的理解程度。理解一份代码最好的方式可能是重新写一遍。
这条路走下去的坑是什么?有的人提议,我们需要用 Event Sourcing。有的人又4 e K j提议,不对,我们应该 Reactive。有的人又提议,我s + E g 8 2们应6 Z ~ + ` 8 t该 Structured State Machine。每个人+ ; j A . C } 7都会p 7 Z h 7 ~ R Y提出自己所谓的“认知负担”最低的表述方式。但是坑在于,每个人的思维习惯,过往经历是不同的。不是所有的 GUI 都一定要 React,要 Reactive,有的人,有的项目,可能 jQuery 直接改 DOM 才是“低认知负担”的解决方案。有一个说法是 Simple v.s. Easy,就是可能一个解决方案是 Simple 的,但是因为不是代码的阅读者所熟悉的模式(比如 Haskell Do Applicative),那对他来说就不是 Easy 的。编程范式这个东西,炒来炒去,就那么几种。如果有一种显著强与其他的,天下早就统一了。不存在什么未知的逻辑表述方式还没有发现出来,早就被枚举完了。
反馈周期:另外很多人[ @ t | g D – + S也看到,修改 Gz \ v l – MUI 代码,要很长时间才能知道改得效果是什么。如果能够所见x F ^ J { Z M N即所得,可以极大地缩短反馈周期,可以在同样的时间内,修改更多次H ~ 5。类似的,在本地无法获得生产环境数据,无法运行完整的代码的情况下,需要上线或者提交到某个特殊的环境才C u G .能跑,这样也会导致反馈周期很长。如果能够降低认知负担,能够缩短反馈周期,岂不美哉?
这条路走下去的坑是什么?编程语言茫茫多1 x / % \ + _,运行时平台年年换,框架和库城头变幻大王旗。这些缩短反馈周期的工具和技术,都强依赖于项目使用的编程语言,运行时平台,框架和库。甚至还有可能要侵入到业务代码的逻辑代码写法。你可以在 Python 中用 viztracer,PHP 中有么,Closure 中有么?给 Html + Vue 好不容易整了个 Vite 出来,迭代速度快了,明天业务就改成用微信小程序了,之前的技术都用不上了。
4、同事之间的沟通成本很高,时间都浪费在) 9 1 e 2 + L开会上了
大型软件都不是一个人可以完K # ) Z 6 # B k 8成的。和同事的配合就要沟通开会。如果能够让每个人都负责一个独立的模块,模块之间松耦合,各搞各的,岂不美哉?编译的时候再把模块代码链接到一起去,变成同一个可执行文件放线上去跑。
这条路走下去的坑是什么?产品经理是不知# F \ Y u q M Z {道你们怎么拆分模块的。产品经理看Z t e z 4到的是这里有一个界面,谁来负责这个界面的,我找m { 2 ! n :谁聊需求。产品经理看到这里有一个按钮可以点,是谁来处理= T z M c ?这个按钮点击的,我找谁聊需求。但是需求往往都是“{ $ r | o I集成需求”,就是一个模块搞不定。比如说订单详情页,需b = / @ w A要各种各样的数据,如果这些数据都在同一个模块里,那就达不到拆分开发的目的。如果分散到了不同的业务模块里,那就得在界面上集成起来。
另外出了故障算谁的?谁来查 bug?谁来发布新代码?别人改的代码,要合1 O C 8 ~ f并到一w V Z R V起,你敢上线么?
5、一个需求要很多个微服务一起配合修改,联调和上线都要小3 [ r V x \ l 4心翼翼,慢慢吞吞的搞
前r W l f t Y ~面说了不拆微服务,只搞代码模块拆分有坑。那微服务就没有浪费了么?
微服务一多,就开始有人问,为啥要拆那么多个微服务。做个需求要改那么多个微服务,不但要联调,上线还有顺序依赖。一个微服务接口只C = }要暴露出去了,就没法下掉了,天晓得哪里还有对它的引用。一个团队能完9 = : z u整搞定一个需求多好。要么就是单体,真香。要么就是拆分不合理,要 DDD 指导微服务的边界划分。
这条路走下去的坑是什么?没有所谓的“一个需求”。需Q q U B C B : a求的粒度是人为限定的,可粗可细。G | 4 E 1 Q E ^不可能达到一个需求一个团队来搞定的,因为需求就没# [ I H P # t l有严格的定义。同时商业创新往往是有破坏性的,就是把之前没有集成关系的集成起来,原来老死不相往来的东西,联动起来。咋调整都不可能避免团队之间配合的。
那么合微服务,减少微服务之间的~ g + 4 H \ B Public API 总是可以吧。_ Q J 1 ,比如让前端和$ x 9 l | P 6 K T后端同4 ] n % 6 ! ? M时发布,这样就不需要考虑后端 API 的兼\ Z I d l容性问题了。合并 B 端: { – U和 C 端,这样就不用考虑 B 端没升级,C 端升了怎么[ C & @ c兼容的问题了。
这条路走下去的坑是什么?很多运行时平台无法实现前端和后端同时发布。比如 iOS 需要审核,需要用户手动确认升级。Android 也有可能没有热更新技术。所B E Z ~ % u以客户端就得兼容旧的版本,字段加了就是不能删。B 端和 C 端合并,服务端可能没人有意见。但是客户端合并到一起,无论是说同一个web域名,还是同一个微信小程序 appid,都可能引起产品经理的强烈抗议。人们习惯了给不同的角色用户,提供一个独立的端。
6、最终用户懂自己要什么,他们可以搞得定 Excel,那我们也可以把软件搞成 Excel 那样,避免因为提需求排期造成浪费
很多软件都会提供一个流程图一样的界面,让用户可以. H F C F去做一些流程修改或者新建一个自动化流程,减少人工重复劳动。还可能提E ! g c R `供一些填写数学公式的8 & X : o q f :地方,让用户填填促销规则。还有一些营销页面搭建的{ d \ q & C . P工具,会让用户直接把页面要什么,用 Photoshop 那样直接拖拽出来。
这条路走下去的坑是什么?如果用户可以 100% 满足任意的自定义需\ ( . N P求,那么这些“用户定制功能”,就得和专业程序员使用的工具等价。这些让用户表达需求的界面往往开发难度很大,需要投入很大的成本。而且未必产生了和成本对等的收益。在某些996国度,人们可能觉得提个需求让人来做会更快& [ ( V U t \一些。
另外一个坑是用户只所以是用户,因为, V 3他们的本职= 6 I L U 8工作不是“软件开发”。如果让用户定制大量的逻辑,那可能工作量会大到创造出了“全职工作”。这个时候,用户R b N n就不是所谓的“用户”了。只是另外一批专职的开发者,拿着所谓的“搭建工1 C e c $ g x J +具”,用蹩脚地方式写代码罢了。
最大坑在于过度吹嘘这种面向最终用户,提供的定制j e v 7 + # L ; y能力,吹嘘成颠覆行业的xxx。能够快速定制的前提在于需求是固定的。只要需求超出了原先配置能力的范围,就需要引入大量的“定制”,这些定制不管是 c# 写 partial method,还是用 blueprint 拖拽流程图,关键是在于“大量”。只要定制的量上来,量变就会引起质变。所以前提一定是砍需求,不能什么需求都满足,才能达到* p ! 0 r提效。闭口不提需求限制,只吹嘘10x提效的,都是Q X 6 \ n m骗子。
收益总是被过度预期,成本总是被过度低估
在种种提效的努力中,看/ M 2 # a R到三个常见的现象
- 人们总是非常乐观,这个提效手段上了之后,直接就可以 10x 哇q R ` N i X。
- 人们又总是低估了代替现有成熟方案,模式,框架所引入的成本。这种成本投入在前半段可能完全是负产出,只有达到一定积累之后,才开始超出原有的体验
- 不管是哪个思路去搞提效,大家都会说自己做的是@ \ S Q i l j“低代码”