4

软件开发提效哪有那么容易,都是坑啊~

 3 years ago
source link: https://zhuanlan.zhihu.com/p/370490326
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

软件开发提效哪有那么容易,都是坑啊~

problem solver


v2-0c74b160267126334d1013f17f53c69e_720w.jpg

提效就是减少浪费吗?

基于现状的各环节浪费进行分析,避免浪费,就能达到提效的目的了么?这么说未必正确,要看目的是什么。有三种可能的目的:

  1. 减少总花费:可能人变少了,但是要开发的时间变长了。
  2. 提高总吞吐:通过堆更多的人,再等同的开发时间里,交付了更多的业务价值
  3. 降低延迟:通过堆更多更多的人,不在乎有多少浪费,只要能快速响应市场就可以

不同语境下说提效,其目的可能是不同的。比如对于前段时间很火的买菜业务,大家不约而同选择的是堆更多更多的人,以降低延迟为目的,不在乎投入的方式来搞。如果为了省几个P5的工资,导致上线开城延迟了一个月,丢掉了市场,那就不值得了。

即便说提效的时候,指的就是消除浪费。如上图所示,我标记了6个可能产生浪费的环节。下面逐个来说每个环节产生的浪费,存在了这么长的时间都是有道理的,都没有那么容易被“提效”。不是说每一条路都走不通,而是说不存在什么低垂的果实,都有坑。

1、产品经理/UI设计师与开发者之间的交接浪费

很多人都看到了产品经理要写一遍 PRD 稿,然后开发者照着翻译一遍。UI 设计师要画 UI 稿,然后前端开发要照着还原 UI。如果能够减少这个交接环节产生的浪费,让 PRD 稿,UI 稿能直接进入下一个环节,岂不美哉。

这条路走下去的坑可能是什么?PRD 稿和 UI 稿存在的意义在于减少返工。如果没有前一道工序,让客户一句话需求直接对接开发。那很有可能做出来了,就不是客户想要的。这个时候要去改代码,比修改 PRD 稿和 UI 稿的代价要大多了。所以 PRD 稿和 UI 稿的优点就是改起来快,没有可运行的代码那么多要求,可以很随意。如果要求 PRD 稿和 UI 稿能够直接翻译执行,那势必要添加语法和语义规则限制。这可能会损害“低成本可修改可讨论”这个优点,产品经理和 UI 设计师要花更多的时间来让产出物符合规范上,而不是花更多的时间和客户讨论反复修改上。

2、开源的库和框架提供的可复用代码太少了,做过很多中后台项目,仍然有大量重复的代码

这个浪费是说,开发者复用的库和框架都是非常底层非常基础的数据结构,RPC通信这些东西。做了个几个项目之后,就会得出自己是 CRUD boy 的想法,觉得总这么重复下去不是办法。如果能够搞出几个开源的库和框架,那岂不是造福人类?

这条路走下去的坑可能是什么?开发者是无法反向约束客户需求的。任意两个客户,即便就是 CRUD 也会有不同的细微差别。比如 list / detail 是上下,还是左右,还是弹框,还是跳页?列表是分页还是无限下拉,是有筛选,还是有搜索?开源库之所以都是那些基础的东西,就是因为那些东西共性大。稍微往靠近用户的一侧靠一些,花样就百出。

然后第二个可能的想法是满足 80% 的需求,那剩下的 20% 让开发者去传参数,传 callback,写 patch,写 DSL 来满足。之前那些开源库的作者没有做到这一点,是因为他们笨(划掉),是因为我有更牛x的代码生成/组件插件技术/xxx

这条路走下去的坑可能是什么?不讨论是不是有什么牛 x 的技术就能大幅改进在已有代码上做定制的体验,我个人经验是不存在这样的技术,不管运行时的还是编译期的,能力上都基本上等价。即便有这样的技术,一方面写 20% 的人至少要知道 80% 是哪 80%,他需要知道已有的库和框架提供了什么,需求是什么,然后 diff 出 20% 的部分。然后还要知道在这个指定的库和框架上怎么写那 20%,没有两个框架提供的扩展方式是一样的,都有自己独特的搞法。

上世纪80年代的时候,流行组件市场的传说。写好业务组件,然后拿出去卖钱。但是从历史来看,最终组件市场的形态是 github 这个最大同性交友社区。最佳的代码复用方式是拿来主义,直接 fork 一份,在别人的代码基础上做修改。啥参数化,插件化,callback,都没有直接改源代码来得直接,好用。

3、现有的代码认知负担太大,新人要很长时间才能接手。反馈周期很长,没法快速修改快速迭代。

观察人是如何阅读代码修改代码的,不难得出这两个主要浪费的点。

认知负担:代码读起来很复杂,不好理解。一份代码要交接给另外一个人来写,他要很长时间才能达到你之前的水平。甚至按照 Programming as Theory Building 的观点,没有人可以达到作者一样的理解程度。理解一份代码最好的方式可能是重新写一遍。

这条路走下去的坑是什么?有的人提议,我们需要用 Event Sourcing。有的人又提议,不对,我们应该 Reactive。有的人又提议,我们应该 Structured State Machine。每个人都会提出自己所谓的“认知负担”最低的表述方式。但是坑在于,每个人的思维习惯,过往经历是不同的。不是所有的 GUI 都一定要 React,要 Reactive,有的人,有的项目,可能 jQuery 直接改 DOM 才是“低认知负担”的解决方案。有一个说法是 Simple v.s. Easy,就是可能一个解决方案是 Simple 的,但是因为不是代码的阅读者所熟悉的模式(比如 Haskell Do Applicative),那对他来说就不是 Easy 的。编程范式这个东西,炒来炒去,就那么几种。如果有一种显著强与其他的,天下早就统一了。不存在什么未知的逻辑表述方式还没有发现出来,早就被枚举完了。

反馈周期:另外很多人也看到,修改 GUI 代码,要很长时间才能知道改得效果是什么。如果能够所见即所得,可以极大地缩短反馈周期,可以在同样的时间内,修改更多次。类似的,在本地无法获得生产环境数据,无法运行完整的代码的情况下,需要上线或者提交到某个特殊的环境才能跑,这样也会导致反馈周期很长。如果能够降低认知负担,能够缩短反馈周期,岂不美哉?

这条路走下去的坑是什么?编程语言茫茫多,运行时平台年年换,框架和库城头变幻大王旗。这些缩短反馈周期的工具和技术,都强依赖于项目使用的编程语言,运行时平台,框架和库。甚至还有可能要侵入到业务代码的逻辑代码写法。你可以在 Python 中用 viztracer,PHP 中有么,Closure 中有么?给 Html + Vue 好不容易整了个 Vite 出来,迭代速度快了,明天业务就改成用微信小程序了,之前的技术都用不上了。

4、同事之间的沟通成本很高,时间都浪费在开会上了

大型软件都不是一个人可以完成的。和同事的配合就要沟通开会。如果能够让每个人都负责一个独立的模块,模块之间松耦合,各搞各的,岂不美哉?编译的时候再把模块代码链接到一起去,变成同一个可执行文件放线上去跑。

这条路走下去的坑是什么?产品经理是不知道你们怎么拆分模块的。产品经理看到的是这里有一个界面,谁来负责这个界面的,我找谁聊需求。产品经理看到这里有一个按钮可以点,是谁来处理这个按钮点击的,我找谁聊需求。但是需求往往都是“集成需求”,就是一个模块搞不定。比如说订单详情页,需要各种各样的数据,如果这些数据都在同一个模块里,那就达不到拆分开发的目的。如果分散到了不同的业务模块里,那就得在界面上集成起来。

另外出了故障算谁的?谁来查 bug?谁来发布新代码?别人改的代码,要合并到一起,你敢上线么?

5、一个需求要很多个微服务一起配合修改,联调和上线都要小心翼翼,慢慢吞吞的搞

前面说了不拆微服务,只搞代码模块拆分有坑。那微服务就没有浪费了么?

微服务一多,就开始有人问,为啥要拆那么多个微服务。做个需求要改那么多个微服务,不但要联调,上线还有顺序依赖。一个微服务接口只要暴露出去了,就没法下掉了,天晓得哪里还有对它的引用。一个团队能完整搞定一个需求多好。要么就是单体,真香。要么就是拆分不合理,要 DDD 指导微服务的边界划分。

这条路走下去的坑是什么?没有所谓的“一个需求”。需求的粒度是人为限定的,可粗可细。不可能达到一个需求一个团队来搞定的,因为需求就没有严格的定义。同时商业创新往往是有破坏性的,就是把之前没有集成关系的集成起来,原来老死不相往来的东西,联动起来。咋调整都不可能避免团队之间配合的。

那么合微服务,减少微服务之间的 Public API 总是可以吧。比如让前端和后端同时发布,这样就不需要考虑后端 API 的兼容性问题了。合并 B 端和 C 端,这样就不用考虑 B 端没升级,C 端升了怎么兼容的问题了。

这条路走下去的坑是什么?很多运行时平台无法实现前端和后端同时发布。比如 iOS 需要审核,需要用户手动确认升级。Android 也有可能没有热更新技术。所以客户端就得兼容旧的版本,字段加了就是不能删。B 端和 C 端合并,服务端可能没人有意见。但是客户端合并到一起,无论是说同一个web域名,还是同一个微信小程序 appid,都可能引起产品经理的强烈抗议。人们习惯了给不同的角色用户,提供一个独立的端。

6、最终用户懂自己要什么,他们可以搞得定 Excel,那我们也可以把软件搞成 Excel 那样,避免因为提需求排期造成浪费

很多软件都会提供一个流程图一样的界面,让用户可以去做一些流程修改或者新建一个自动化流程,减少人工重复劳动。还可能提供一些填写数学公式的地方,让用户填填促销规则。还有一些营销页面搭建的工具,会让用户直接把页面要什么,用 Photoshop 那样直接拖拽出来。

这条路走下去的坑是什么?如果用户可以 100% 满足任意的自定义需求,那么这些“用户定制功能”,就得和专业程序员使用的工具等价。这些让用户表达需求的界面往往开发难度很大,需要投入很大的成本。而且未必产生了和成本对等的收益。在某些996国度,人们可能觉得提个需求让人来做会更快一些。

另外一个坑是用户只所以是用户,因为他们的本职工作不是“软件开发”。如果让用户定制大量的逻辑,那可能工作量会大到创造出了“全职工作”。这个时候,用户就不是所谓的“用户”了。只是另外一批专职的开发者,拿着所谓的“搭建工具”,用蹩脚地方式写代码罢了。

最大坑在于过度吹嘘这种面向最终用户,提供的定制能力,吹嘘成颠覆行业的xxx。能够快速定制的前提在于需求是固定的。只要需求超出了原先配置能力的范围,就需要引入大量的“定制”,这些定制不管是 c# 写 partial method,还是用 blueprint 拖拽流程图,关键是在于“大量”。只要定制的量上来,量变就会引起质变。所以前提一定是砍需求,不能什么需求都满足,才能达到提效。闭口不提需求限制,只吹嘘10x提效的,都是骗子。

收益总是被过度预期,成本总是被过度低估

在种种提效的努力中,看到三个常见的现象

  • 人们总是非常乐观,这个提效手段上了之后,直接就可以 10x 哇。
  • 人们又总是低估了代替现有成熟方案,模式,框架所引入的成本。这种成本投入在前半段可能完全是负产出,只有达到一定积累之后,才开始超出原有的体验
  • 不管是哪个思路去搞提效,大家都会说自己做的是“低代码”

我完全同意八叉的观点, 为什么我说低代码是“行业毒瘤”?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK