在软件工程领域,复杂性一直是困扰开发者和设计者的重要难题。如何界定软件复杂性,如何在设计中有效降低复杂度,是提升软件质量和维护性的关键。瑞奇·希基(Rich Hickey)、约翰·奥斯特豪特(John Ousterhout)以及扎克·特尔曼(Zach Tellman)三位业内知名专家分别提出了独特的复杂性定义和认知框架,他们的观点不仅在学术上引人深思,更对实际开发过程产生深远影响。本文将对这三种软件复杂性概念进行系统梳理与对比,帮助读者全面理解复杂性的多重维度。 瑞奇·希基的软件复杂性观点极具哲学意味,源于其演讲《Simple Made Easy》。希基强调“简单”(simple)与“容易”(easy)是两个不同的概念,前者具有客观性,后者则带有主观色彩。
简单意味着事物具有“单一性”——单一折叠、单一角色、单一任务、单一概念和单一维度。他提出“简单是专注于某些方面,而不是将多种东西混合在一起”,强调在设计中避免“complecting”(复杂交织),而更应追求“composing”(组合)。希基从函数式编程的角度批判了状态管理的复杂性,认为状态引入了非简单的交织,而纯函数接口的设计则是实现简单性的有效手段。通过探讨诸如状态、对象、方法、变量、继承、条件语句等多种编程概念,他展示了如何用更简洁的设计代替高复杂度的实现。简单带来的直接好处包括更易于理解、更容易改变、更容易调试以及更高的灵活性。希基的视角突显了软件结构的纯净与专注,提供了客观评判复杂性的参照标准。
约翰·奥斯特豪特在《A Philosophy of Software Design》中提出了另一套复杂性定义,强调复杂性是“所有使软件系统难以理解和修改的结构相关因素”。他将复杂性归因于依赖关系和信息不可见性(obscurity)。依赖关系意味着代码不能孤立理解,修改一处代码往往会影响其它部分;不可见性则指重要信息没有被清晰地展现。奥斯特豪特进一步把复杂性的表现形式概括为变更放大效应(change amplification)、认知负荷(cognitive load)和“未知的未知”(unknown unknowns)。他提出,设计的一个重要目标是减少依赖数量,使依赖关系清晰并且易于理解,以及尽量降低认知负荷,从而减少“未知的未知”。相比希基的客观视角,奥斯特豪特更认可复杂性的主观体验,尤其关注开发者的理解负担。
他主张设计应追求“明显性”(obviousness),即代码读者能快速准确地理解代码的行为和意义。尽管他的论述中部分术语存在相互定义及界限模糊的问题,但其关于依赖性和信息可见性的洞见,为软件系统设计提供了实用的策略和评估标准。 扎克·特尔曼在其通讯《Explaining Software Design》中提出了基于“解释”的复杂性观念,从信息理论和沟通的角度赋予复杂性全新内涵。特尔曼认为复杂性是“所有解释的总和,尤其是面向未来的解释的加权和”,换言之,复杂性不仅仅是代码本身,更是理解和传达代码意义所需的信息量。他引入“惊讶量”(surprisal)的概念,强调复杂性依赖于听众对代码的预期之间的匹配程度。特尔曼划分了解释的三个部分:前缀(听众已有知识,未说出部分)、主体内容(实际编码和文档)、后缀(预期期望将来解释的内容)。
他还赋予“耦合”新的定义,即“两个事物往往需要被一起解释的程度”,不对耦合本身作价值判断,而视其为设计中的一把“双刃剑”。此视角强调解释和沟通是软件开发的核心任务,复杂性则体现在未来交流和维护中所需承担的负担。他的理论使软件复杂性的讨论更加贴近实际开发中的沟通成本和认知负担,具有高度的实际指导意义。 从主观与客观的视角分析三者的差异,希基主张复杂性是客观存在的某种结构状态,是设计中的“交织”产物,追求最大程度减少结构上的“坎坷”。而奥斯特豪特和特尔曼则更多关注人的理解与交流过程,复杂性依赖于观察者的视角、知识背景及团队文化。奥斯特豪特聚焦依赖关系和信息可见性对认知负荷的影响,强调设计应追求“明显易懂”,突出人类的心理感受。
特尔曼则将复杂性抽象为解释的代价和未来交流的负载,更加注重软件生命周期内知识传递的全貌。 在耦合的理解上,希基视“complecting”即交织为负面现象,强调模块间应保持清晰界限,避免概念的混合。奥斯特豪特承认依赖不可避免,但主张依赖应简洁清楚且容易理解。特尔曼直接把耦合定义为必须一起解释的现象,既有成本也有收益,视为设计中不可或缺且中性的属性。例如数据库中的外键约束,希基可能视为复杂交织,奥斯特豪特认为只要依赖明确即可接受,特尔曼则重点判断两者是否经常需要共同解释,从而合理利用耦合带来的优势。 分析复杂性对团队新成员的影响时,三种定义也体现不同指导价值。
希基的客观复杂性判断无法直接解释新人成长曲线,复杂系统是否复杂一目了然,主观“难易”属使用者问题。奥斯特豪特的观点则提示复杂代码会造成开发障碍,是设计缺陷的体现,指出减少依赖和增强明显性可提升团队续航力。特尔曼的解释成本观点更契合实际管理情境,突出“未来解释”的代价和团队交流负担,促使管理者从组织知识传递和能力底线出发制定策略。 对于软件复杂性的良好定义,笔者认为应达成三点目标:与现实世界实例高度契合,推动团队成员对复杂度的共识形成,并具备广泛可适用性以检验不同环境中复杂性的表现。特尔曼的解释视角优势明显,在突出团队协作、沟通负担和认知成本上更胜一筹,提供了理性而灵活的框架支持软件开发全生命周期管理。希基的客观简单理论为代码结构的纯粹性和可理解性提供基石,奥斯特豪特则为设计中的依赖和信息透明度注入实用策略。
总的来说,三者的结合有助于形成多维度、全方位的复杂性认知,为软件设计与维护指明方向。 当今软件开发面临愈发复杂的系统结构与团队协作挑战,单一视角已难涵盖复杂性的全部内涵。通过运用希基的“避免交织”、奥斯特豪特的“减少依赖且增强明显性”、以及特尔曼的“优化解释负担”理念,开发团队可以在实践中更好地平衡结构合理性、认知便捷性和沟通效率。深入理解三位大师的复杂性定义,助力软件开发者和管理者做出更加明智的设计选择,推动软件行业向更简洁、透明且高效的方向不断演进。