解锁软件设计的奥秘:《软件设计的哲学》深度解读
创作时间:
作者:
@小白创作中心
解锁软件设计的奥秘:《软件设计的哲学》深度解读
引用
CSDN
1.
https://blog.csdn.net/arong_xu/article/details/145601510
《软件设计的哲学》一书由John Ousterhout撰写,深入探讨了软件设计中的复杂性问题,并提出了一系列设计原则和实践指导,旨在帮助开发者减少软件复杂性,提高代码的可维护性和可扩展性。
这本书的作者John Ousterhout是业界知名专家,拥有丰富的编程经验,参与过众多大型项目,如创建Tcl脚本语言,在分布式操作系统和存储系统领域也取得了显著成就。正是这些宝贵的经验,让他在书中分享的见解深刻又实用。
书籍要点
1. 复杂性的定义与表现
书中开篇就点明,复杂性是软件设计的头号难题。它就像软件里的"暗物质",看不见摸不着,却处处影响着软件开发的效率和质量。
- 复杂性的定义:只要是跟软件系统结构相关,让系统难以理解和修改的东西,都是复杂性的表现。
- 复杂性的表现:
- 变更放大:简单的修改需要多处代码改动
- 认知负荷:开发者需要掌握大量信息才能完成任务
- 未知的未知:不清楚哪些代码需要修改或需要哪些信息
- 复杂性的原因:复杂性主要由依赖关系和模糊性引起。依赖关系是指代码之间的相互依赖,模糊性是指重要信息不明确或难以理解。
2. 战略编程 VS 战术编程
- 战术编程:以快速完成任务为目标,通常会导致代码质量下降,复杂性逐渐积累。战术编程只盯着眼前功能实现,不管以后的事,这样会让系统越来越复杂。
- 战略编程:注重长期代码质量,通过投资时间来改进设计,减少复杂性。战略编程的核心思想是“代码只是能运行还不够”,开发者应优先考虑系统的长期结构,而不是仅仅完成当前任务。
作者建议我们在开发过程中,要不断地做小投资来优化设计,比如花 10% - 20%的开发时间来思考设计问题,这样既能保证项目进度,又能提升软件质量。
3. 模块设计
- 模块化设计:将系统分解为相对独立的模块,每个模块有明确的接口和实现。模块的接口应尽可能简单,隐藏复杂的实现细节。
- 深度模块:深度模块是指功能强大但接口简单的模块。深度模块通过隐藏复杂性,减少了系统的整体复杂性。
- 浅模块:浅模块是指接口复杂但功能有限的模块,通常会增加系统的复杂性。
对于一个模块来说:接口(Interface)越少越好;功能(Functionality)越多越好。
4. 信息隐藏与泄漏
- 信息隐藏:模块应隐藏其内部实现细节,只暴露必要的接口。信息隐藏可以减少依赖关系,简化接口。
- 信息泄漏:当设计决策在多个模块中反映时,会导致信息泄漏,增加系统的复杂性。应尽量避免信息泄漏,确保每个模块只负责特定的功能。
5. 通用模块 vs. 专用模块
- 通用模块:通用模块的接口应设计得足够通用,能够适应多种使用场景。通用模块通常比专用模块更简单,更易于维护。
- 专用模块:专用模块的接口通常与特定功能紧密耦合,容易导致信息泄漏和复杂性增加。
6. 不同层次的抽象
- 不同层次的抽象:系统中的每一层应提供不同的抽象,避免相邻层次的抽象过于相似。如果相邻层次的抽象相似,通常意味着模块分解存在问题。
- 传递方法:传递方法是指只调用其他方法而不做任何额外工作的方法,通常表明模块的职责划分不清晰。
7. 将复杂性向下推
- 将复杂性向下推:模块应尽可能处理内部的复杂性,而不是将复杂性暴露给使用者。模块的接口应尽可能简单,即使这意味着模块的实现会变得更复杂。
8. 代码的合并与分离
- 合并代码:如果多个模块共享信息或功能,通常应将它们合并为一个模块,以减少接口复杂性和信息泄漏。
- 分离代码:如果模块的功能过于复杂或职责不清晰,应考虑将其拆分为多个模块。
9. 消除错误
- 消除错误:通过重新定义 API 的语义,减少异常和错误处理的需求。例如,某些操作可以通过默认行为避免抛出异常。
- 异常屏蔽:在低层次模块中处理异常,避免将异常传播到高层次模块。
- 异常聚合:将多个异常处理逻辑合并为一个统一的处理机制,减少重复代码。
10.设计两次
- 设计两次:在设计模块或系统时,应考虑多个设计方案,并比较它们的优缺点。通过设计两次,开发者可以更好地理解问题,并选择最佳的设计方案。
11.注释的重要性
- 注释的作用:注释不仅仅是解释代码,它们还帮助隐藏复杂性,提供抽象。注释应描述代码中不明显的信息,而不是重复代码。
- 注释的层次:注释可以分为接口注释(描述模块的接口和行为)和实现注释(描述代码的内部实现)。接口注释应尽可能简洁,避免暴露实现细节。
实践指导
软件设计的核心目标是减少复杂性。通过遵循书中的设计原则,开发者可以创建更简单、更易维护的系统。复杂性是不可避免的,但通过良好的设计实践,可以有效地控制和管理复杂性。
- 避免浅模块:模块的接口应尽可能简单,隐藏复杂的实现细节。
- 信息隐藏:模块应隐藏其内部实现,减少依赖关系。
- 设计通用模块:模块的接口应设计得足够通用,能够适应多种使用场景。
- 将复杂性向下推:模块应尽可能处理内部的复杂性,而不是将复杂性暴露给使用者。
- 消除错误:通过重新定义 API 的语义,减少异常和错误处理的需求。
- 设计两次:在设计模块或系统时,应考虑多个设计方案,并比较它们的优缺点。
热门推荐
如何记忆:一种简单的长期记忆技巧
张雪峰谈十大高薪专业排行榜(含专业介绍,就业方向)
解析开学恐惧症:学业、人际、家庭和生活节奏的多重压力考验学生心理
中医里抑郁症是怎么回事
如何操作手刹以确保停车安全?这种操作对车辆保护有何重要性?
北京老字号六必居
如何在电商平台上做好产品控价?
明朝文学十大代表作:从《三国演义》到《紫钗记》
猫咪的专属“草本乐园”:四种猫草的神奇功效大揭秘
魏玛共和国与纳粹党的崛起
三支一扶和西部计划哪个更好
三角形外心:几何图形中的中心点
探索兔子的视界:从视野到眼部护理
英美港澳本科学费持续上涨!
探索儋州:必尝的地道美食与餐饮指南
有哪些英英词典网站比较好的
研究表明,小型模块化反应堆可帮助印第安纳州实现全天候无碳电力,并带来经济效益
眼睛干涩?夜盲?都和它有关!一篇文章教你补回来!
婚前检查的法律依据与具体内容
一文详解鼻窦炎手术:三种常见术式及注意事项
老公的称呼有哪些?探索不同文化与情感的表达方式
抗生素就是消炎药?千万别过度使用抗生素!阿莫西林、头孢属于……
毛囊的 “生老病死”:头发命运的幕后主宰
多芯片封装(MCP)的全面解析
四川适合种植的花卉及栽培要点
四色安全标志全解析:红黄蓝绿各有何含义?
客服艺术:掌握五大在线客服沟通技巧,提升客户体验
结核病有哪几种
石雕观音:象征寓意的文化渊源与解读
消弥“温差”,上海推出市场准入登记便利化10条措施