软件工程的难题

2024-04-08  本文已影响0人  duzhongli

软件开发有一个难题,叫做"扩展"(scaling),即怎样服务更多的用户。 10000个并发用户,跟10个并发用户,这是完全不同的概念,哪怕功能完全相同,背后的实现是完全不一样的。并发用户数上升一个数量级,软件就必须重构,大量问题随之产生。

大项目的技术难度高,管理难度更高,而且大团队的生产率往往很低,行动缓慢。 “软件工程就是研究,如何扩展软件和团队,适应大项目的需要。

推荐两本书:《加速:构建和扩展高性能技术组织》,《规模:生物,城市和公司的普遍法则》。

推荐文章:Code rant: Decoupling, Architecture and Teams (mikehadlow.blogspot.com)

下面是一些摘录

一,大项目的困境

一个典型的大型软件项目,开发过程通常是下面这样。

最开始是一个小项目,开发人员两三个人,甚至可能只有一个人。产品比较简单,功能很有限。

第一版发布,拿给客户使用,反响不错。客户要求的新功能,很快开发出来,Bug 修补也很快,因为早期客户往往可以与开发人员直接沟通,快速反馈。

公司决定投入更多人员,开发这个项目。团队慢慢变大,软件开始变得复杂,开发速度逐渐变慢,2.0 版花费的时间比预期要长一点。Bug 的修复难度开始增加。总之,新功能的开发日程变久了。

进一步扩充团队。但更多的新成员其实会降低其他人的生产率,一个普遍现象是团队规模越大,每个人的平均生产率越低。

几年以后,代码逐渐老化,复杂性不断增加,项目开始停滞不前。某些极端的情况下,软件的维护成本变得非常高昂,并且几乎不可能进行更改。最终,这个项目成为技术债务,等待被新项目替换

二、为什么大项目的开发效率低?

(1)代码复杂度

随着代码量的增长,单个开发者想要理解整个代码库,变得越来越困难。如果团队超过五个人,每个人负责一个功能,那么单个人几乎不可能追踪系统的所有工作进度。

当中途加入团队,整个项目是一个紧密耦合的大型系统,你又不理解系统的每一个工作细节。这时,你就不太敢修改以前的代码,因为不知道随之而来的全部影响。

不真正理解系统,你也就不会感到自己是代码的主人。会很犹豫要不要重构,过时的代码开始累积,技术债务就这样出现了。长此以往,开发变得越来越不愉快和令人无法满意,最终导致人才流失。后面接手的新人,更难于重构那些遗留下来的代码。

(2)团队原因

随着团队成员的增加,交流成本开始指数式上升,团队人数越多,协同的难度就越大

大团队保持扁平化管理,也会越来越困难,必须拆分成较小的群体。这时,对等的交流会被自上而下的交流所取代。团队成员会感觉,自己从平等的利益相关者,转变为普通的工作人员,工作动机受到了影响,责任感和主人翁意识都会淡漠。

管理层为了解决问题,会尝试组建新团队和新的管理架构。但是,不管怎么做,大型组织都很难保持所有成员的积极参与。

三,解决方法:代码解耦

大项目的开发效率不高,把这个问题归咎于程序员的技术水平低和管理不善,都是没用的。 根本原因是软件规模的增长,必然使得代码和团队变得笨重。 除非很早就认识到问题的根据,采取缓解对策,否则前面描述的情况,迟早都会出现。

解决这个问题,要从代码和团队两方面着手。

代码层面的解决方法是,将软件解耦,拆分成组件或者模块,防止各个部分紧密地耦合在一起。每个组件和模块,都可以独立开发,通过公开的接口被其它部分调用。

这样的话,就大大减轻了开发者的负担,只需要负责自己的代码即可,不需要关心其他部分的实现。每个部分都可以单独重构,不担心影响到其他部分

四,解决方法:团队解耦

团队层面也需要解耦,要把人员分开。

这可以参考互联网的架构,它之所以能够扩展,是因为它由一个个独立的节点组成。为了防止节点之间互相依赖,各个节点都遵循以下公开的通信协议规则。

(1)不需要了解其它节点的内部实现,就可以与之通信。

(2)节点之间不直接共享状态,只通过通信交换数据。

(3)每个节点单独开发和部署。

大团队也应该遵循类似的原则,进行解耦。

(1)每个子团队都可以独立运作,不依赖外部人员。

(2)子团队内部的运作,不需要被外部知道。

(3)子团队之间的协调,应该按照公开的协议和规则,最好能够自动完成,避免私下协商。

五,团队解耦的注意点

(1)每个子团队最好不要超过5个人

(2)子团队应该是一个小型的全功能软件开发组织

很多大团队按照人员角色分组,比如架构组、开发组、DBA 组、测试组、工程组等等,这是错误的。这样完全没有解耦,还是瀑布式流程,各组之间依然互相依赖,工作时必须与别组单独协商。而且,可能会产生利益冲突,比如,开发组希望尽快交付,而测试组希望多一点时间测试。

正确做法是按照软件的业务功能分组,每组负责一个全流程的软件大功能,设计、编码、测试、部署、支持等人员都在同一组。这样才能做到解耦,以及独立的交付和重构。每组内部使用什么工具、如何实现某个功能,都是自己决定,各组之间不需要共享内部细节,也不依赖别组的工作。

(3)大团队应该保障子团队的自主权,按照子团队提供的功能和商业价值,进行资源分配。

(4)软件架构师的角色很重要。

软件架构师的关注点,不应该是团队使用的工具和技术,而是各种服务与整个系统运行状况之间的协议和通信保证代码和团队可以正确解耦

(5)代码解耦和团队解耦的关系。

理想情况下,代码解耦与团队解耦保持一致,形成一对一的关系,一个子团队负责一个独立的模块。实际运作中,一个子团队负责几个模块也可以,但是一个模块不能由多个子团队来参与

(6)通信(模块之间的、子团队之间的)尽量规范化,争取做到过程简单、文档充分,最好有规范的 API,这样无需任何人员交流,就能建立通信。

上一篇下一篇

猜你喜欢

热点阅读