导航

软件复杂度

Posted on 2022-11-30 09:31  蝈蝈俊  阅读(324)  评论(0编辑  收藏  举报

在 《人月神话》和《卓有成效的程序员》这两本经典的书籍中都提到:

软件设计与开发的核心就在于控制复杂度

软件为什么会出现复杂? 有哪些复杂问题? 有什么通用的解决方案呢?我们从下面两种拆分方法来看:

一、空间 + 时间 + 人

在看软件复杂度时,除了时空信息之外,还应看人这个不确定因素。

空间复杂度

依赖多,规则多,客户多,流量大这些都是空间维度可能会面临的问题,在这样的背景下,相关领域知识需要每个参与者都掌握,这里如果存在认知偏差,就会造成需求和交付的偏差。

空间复杂度的解决套路:

  • 关注点分离:业务上按照通用&非通用,核心&非核心,主流程&辅流程做分离;技术上按照功能性需求&非功能性需求分离。
  • 依赖原则依赖稳定,对内对外服务必须有SLA机制;依赖服务抽象化,对外接口不依赖服务实现细节;分层依赖,上层服务不依赖下层服务,平台业务稳定性不依赖业务方服务;组合优于继承,减少依赖。
  • 认知减负: KISS原则,简单就是美,若无必要,勿增实体;统一语言,尤其是组织内部对同一事物、各种名词概念理解一致;统一架构规范,包括代码规范、架构分层规范、上线发布规范等;文档既代码,防止信息丢失,做好知识传承。

时间复杂度

“天下武功,唯快不破”,互联网产品更是遵循这样的规律,一招鲜吃遍天,慢竞争对手一步,可能就会被淘汰出局。在这种快速试错的环境下,我们需要更早地交付业务价值。因此,很多时候产品无法深思熟虑,开发也未必有都有充足时间详细设计。因此我们往往在知识最不充分的时候,做出了最重要的决定。

时间复杂度的解决套路:

  • 迭代开发:按照敏捷迭代开发模式,随着每个迭代,不断获取市场和用户对产品的反馈以及环境(竞对、技术等)的变迁,不断建立新的认识,在随后的迭代计划中做出调整,响应具体的变化。
  • 战略编程,是指重视设计并愿意投入时间,短时间内可能会降低工作效率,但是长期看,会增加系统的可维护性和迭代效率,但必须要做到不过度设计。
  • 适当的扩展性,比如:预留字段,通过流程引擎来满足工作流程的快速响应,通过UI组件化配合UI的编辑器来快速调整用户界面的变化;通过插件技术来将容易变化且相对复杂的逻辑从主流程中剥离出来进行扩展等。

人员复杂度

软件是人大脑的思维产物,互联网最重要的资产就是人。人员复杂度就类似让一群高智商人群,像一群舞蹈演员对外部(如音乐)感应作出合理响应,并且与舞伴进行默契的行动、表情配合,始终呈现一些良好的作品。

人员复杂度的解决套路:

  • 情境管理:正视人的成长诉求和规律,根据能力&意愿进行合理工作分配,并做好核心岗位的人员互备工作;
  • 减少不必要的协同:比如“两张披萨饼团队”,只有绝对必要时才召开会议。
  • 理性思考:建立指标体系;在各个环节可引入“第十人理论”,防止出现重大错误。

二、业务 + 技术 + 项目管理

软件研发的复杂工作主要有这些:

  • 业务复杂度: 从客户(利益相关方)视角看;
  • 技术复杂度: 从实现视角看;
  • 项目管理复杂度: 从协作视角看;

软件复杂度 = 业务复杂度 + 技术复杂度 + 项目管理复杂度

业务复杂度

业务复杂度对应了客户的业务需求,比如业务流程多,参与者多等,因而这种复杂度往往会随着需求规模的增大而增加。

业务复杂度解决套路:

  • 提前想全各利益相关方。
  • 站在更高层抽象提炼各方诉求。
  • 尽可能的拥抱变化,做到关注点分离。

技术复杂度

技术复杂度来自需求的质量属性,诸如安全、高性能、高并发、高可用性、低成本等需求,为软件设计带来了极大的挑战。让人难受的是这些因素彼此之间又可能互相矛盾互相影响。

技术复杂度解决套路:

  • 按照业务特征做取舍:用空间换时间,用时间换空间。
  • 关注行业新技术适用场景。

项目管理复杂度

项目管理复杂度:随着参与方的增多,沟通的成本会指数级放大。项目管理的挑战在有限的资源约束下,以项目成功为目标的对项目全过程计划、组织、指挥、协调、控制、评价。

项目管理复杂度解决套路:

  • 确保参与方目标一致。
  • 定期做好信息同步,定期收集反馈。

总结

复杂度增长带来的风险往往是后知后觉的,等到问题出现时,往往已经形成一段时间,或者坑往往是很久以前埋的。

如果你所写的业务代码生命周期只有几个月,那么多半在代码变得不可维护之前就可以下线了,那可以不用关注太多,能用就行。但是如果不是,我们就需要尽力控制,就算是因为进度而临时打破窗户也要尽快补上,避免腐化到问题很严重了。