软件的“摩尔定律”,是不断提升软件生产效率,以降低软件的开发成本和上市时间。在软件“摩尔定律”的驱动下,诞生了各种软件开发的语言、架构、工程和模式。
每年都有新的编程语言出现。设计模式,据说已经超过 300 种。各种眼花缭乱的概念和技术,有些还相互矛盾,真伪难辨。借用政治经济学的一个说法,符合软件生产规律的,就促进软件生产的发展,不符合软件生产规律的,就阻碍软件生产的发展。
软件生产的规律是什么?总结了几点,不敢轻易说是规律,就是常识吧,供大家指正。
减少开发人员之间的等待和依赖
《人类简史》上说,一个猩猩自然群体中的个体数,一般不超过 20-50 个。人类,高等一点,增加了八卦等连接力,也不超过 150 个,再多就要靠文化、制度、意识形态等虚拟的东西来连接了。作为一个软件开发团体,也不是越大越好。团队规模越大,开发人员之间的沟通、配合、等待和依赖越多,效率就越低。但开发人员太少也不行,靠什么来解决这个软件生产上的矛盾呢?
什么是架构?
越熟悉的词,越不好找一个准确的定义,这里抛一个我觉得是最接近的。Architecture 一词最早来自建筑,是在复杂场景下,解决人的分工、沟通和配合问题,以达到更高效率和更高目标。软件架构就是解决软件生产过程中人员的分工、沟通和配合问题,以及软件生命周期中的维护和扩展问题。显然,解决这个矛盾,架构很关键。
架构让生产人员在技能、工序、配合上充分解耦。盖一栋楼,先是打地基搭框架的人上,然后是砌墙的人上,最后是装修的人上。做软件也一样,如果每个人能够在不相互等待和依赖的情况下,把自己负责的部分做好,拼到一起就能 Run,那就是最理想的情况。
从模块化,组件化到服务化,基本也是顺着这个思路在发展。一个团队,接到一个开发任务,先做需求分析,系统分解,每个人分一个模块,各人先聚焦自己的模块。在开发阶段,基本是可以做到解耦的。但在验证和运行阶段,麻烦就接踵而至。一个模块的验证要等待其它相关模块就绪后才能进行,一个模块的修改可能会依赖另一个模块的同步修改,一个模块的问题可能会导致另一个模块崩溃。随着时间的推移,血肉模糊,纠缠不清,无数软件开发人员的大好青春就耗在这里。
经过血泪教训,开发人员自然会想到,把一些公共的功能和框架提取出来,做成组件,提前开发并验证好,确保组件部分没有问题,然后再基于组件,增加适配代码去搭建系统。相比初始的模块化,组件化在效率上肯定有优势。但组件并不能端到端地独立验证和运行,并没有从根本上解决耦合和依赖问题,组件化本质还是一种模块化。由于组件共享程度高,依赖大,还容易成为瓶颈。
服务化架构是在此基础上的进一步发展,不但是在开发阶段解耦,而且是在验证和运行阶段解耦。
为什么在验证和运行阶段解耦很重要?
老开发人员都知道,一个全新系统的开发,耗时最长的往往不是开发阶段,而是联调阶段。联调特别耗时耗力,因为各部分都不能独立地验证和运行,需要集成在一起才能验证和运行,联调中耗时最多的就是等待。服务化,就是希望每部分尽量都是一个自治的系统,能够独立地开发、验证和运行。一个服务内部的修改不需要其它服务同步修改,一个服务内部的问题对其它服务的影响降到最低,把开发人员之间的配合、等待、依赖和影响降到最低。下面这张图,可以帮助理解从模块化到服务化开发模式的区别。
服务化架构(SOA)早就有了,为什么近来微服务很火?道理也很简单,当前微博比博客流行,微信比信流行。小了之后就能有更多的应用场景。深层次的原因,感兴趣的可以去探究。
模块化,组件化,服务化只是架构的一类模式。基于适合的场景,尽量减少开发人员之间相互的等待和依赖,就是好架构。
问题的早期暴露和快速修正
写完一篇作文后就检查,发现的错误立刻修正,效率最高。如果等几个星期甚至几个月后再去检查,灵感和思路全无,效果肯定不好。这是生活中的一个常识,同样适合于软件生产。软件生产很重视代码 Review、UT/IT/ST,生产过程从瀑布模式到迭代模式,这些都是为了问题的早期暴露和修正。但光靠这些还不够,还是会有缺陷遗留到后端。让问题在开发过程中早期暴露,快速修正,看似一个常识,但可怕的是,有些开发人员在问题的泥潭中迷失了这个常识。软件迭代开发,要关注几点:
01 健康迭代
迭代模式相对瀑布模式的进步,就是问题的早期暴露和修正。如果每个迭代的 DI 值都很高,那就和瀑布没有区别,甚至更差(压缩了前期的 Review 和 DT)。现在公司所有的产品都号称迭代,但不健康的迭代开发在基层团队还非常普遍。在进度的压力下,新需求开发优于问题解决。少数团队为了让 DI 数据不难看,甚至让测试人员停止测试,掩耳盗铃。
在迭代快结束时集中解决问题,亚健康
在迭代快结束时试图解决问题,未达成,很不健康
每个迭代的 DI 值都很高,极不健康
能够做到主干持续健康,绿色主干,随时可发布的产品不到 10%。
02 开发人员做 SDV
传统软件生产分工中,开发人员做 Code/DT(UT/IT/ST),测试人员做 SDV/SIT/SDV。我 2010 年带 PDU 时,赶上把测试人员纳入 PDU,当时我就推行开发人员做 SDV。出发点只有一个,就是开发人员完成功能验证后再把代码交给下个环节,本质也就是问题的早期暴露和快速修正。功能性问题往往阻塞测试,需要一群人来定位,确定是谁的问题,定位出来后,测试再提单,开发人员修改,重新出版本,升级版本,非常影响测试效率。开发人员自己做功能测试,问题小闭环,减少测试阻塞,提升效率。看起来很好的事情,推行过程中遇到很多阻力,开发人员觉得做了不该做的事情,测试人员觉得被人抢了饭碗。
客观上也有一些困难,比如开发人员搭 SDV 验证环境的效率比较低。但这个目标还是坚持了下来,除了开发人员和测试人员观念上的改变,软件工程能力的进步也是一个推动力。持续集成,持续验证的意识也逐渐深入人心。我不知道现在公司其它产品开发中,能否都做到开发人员自己做功能验证,把没有功能性问题的代码交给测试人员,大家可以自检一下。
回到出发点,敏捷、健康迭代、持续集成、开发人员做 SDV,等等,如果能匹配应用场景,让问题能早期暴露,快速修正,那就是符合常识的好方法。
本文转载自华为云产品与解决方案公众号。
原文链接:https://mp.weixin.qq.com/s/wx_uaYEPOuybOHYOVWHZ_w
评论