
张刚
本书介绍了高效的软件设计和编程方法,把精益需求分析、领域驱动设计、面向对象、契约式设计、测试驱动开发、意图导向编程及演进式设计等编程实践融会贯通,深入洞察软件设计本质,展示了一个清晰的程序员编程能力提升路线图。全书共十二章,按照程序员技能提升的顺序,分为品味篇、专业篇和高效篇。 本书适合各种编程语言的一线开发者、大学计算机和软件工程相关专业三年级以上本科生或研究生阅读,也适合专业的软件开发团队作为统一编程范式、提升设计意识和能力的参考书。
很优秀的一本软件设计书籍,看完后学到很多。
期待看到作者在 ai 时代对本书的内容更新!
强烈推荐,书本知识成体系,从需求分析,到领域建模,到编码实现整个流程的知识都有涉及,书中知识、案例通俗易懂,也体现出作者对专业知识非同一般的功力。感谢作者写了这本书,庆幸自己能看到这本书!
我的理解,软件设计参考计算机架构就很简单:模块(输入模块,输出模块,中央处理器,存储模块,调用模块,电源模块,等等),联结关系,接口,……等等,可以替换、迭代,不知道我是理解是不是太简单了😂
从需求分析到编码实践,各个环节的高质量实现都进行了讲解,可以用于快速构建如何完成高质量软件的开发这一问题的知识框架。
我觉得这本书很适合现在的我,之前学习过一些关于简洁代码,设计模式,设计原则,重构,测试驱动开发,架构整洁之道的知识,但一直在项目整体开发中应用的不流畅;读《软件开发》过程中,有一种互相融会的感觉,使这些单点知识串联在了一起。例如,项目或需求开发整体流程:需求分析、领域模型设计、由外而内开发,开发中使用合适的接口和契约(利用设计原则和设计模式,进行组件设计与组件之间的协作),测试先行;还例如,将原来零散的知识,内聚起来,向上抽象出一个层次;高质量测试、代码评审、结对编程、静态扫描工具,都是为了提高代码质量;重构、测试驱动开发、持续集成,都是为了使软件持续演进。 读完之后开发的目标发生了转换:原来想的是要写出优质的代码;现在目标是:为实现有价值业务,流畅的写出优质代码。其中增加了两个重点:一个是有价值需求,另一个是流畅的写出(过程中自己感到流畅,更能享受其中)。这个目标与精益思想提到的原则也比较符合。以终为始(有价值、优质代码:高质量 可读性 复用性),流畅的写出(持续拉动),保证质量和持续演进(演进性)。 书中印象比较深的几个点: 1.积极探索业务目标,梳理清楚业务流程,可以使用UML图表示(例如泳道图),还可以使用具体例子说明;三剑客要尽早达成统一。 2.领域模型是对现实世界的认知,通过捕获、辨析、演进来构建领域模型有助于更清晰的认识业务目标。领域设计还有助于拆分服务、组件(战略模式)设计组件(战术模式)。根据领域还有助于架构分层:接口层,应用层,核心领域层,基础架构层。 3.领域模型可以使用UML类图表示,其中空心三角(继承或泛化),实心三角(实现),空心菱形(聚合-拥有关系,例如学校-老师),实心菱形(组合-强拥有关系,例如学生-学生成绩),箭头(关联)。 4.设计原则(SOLID)中单一原则、开闭原则、里氏替代原则来指导类的设计;接口隔离、依赖倒置用来指导接口设计,类之间协作的设计。 5.接口的定义可以从需求方出发,这样的表示需求方需要一个什么样的功能来完成事情,这么设计的好处是需求方更加稳定。接口在提供方一侧,表示提供方提供了一个什么服务,而需求方如果要对接这个服务,最好是搞个适配器,也就是需求方再定义个接口对接外部服务,让外在的服务不影响内部的功能,这也是整洁架构和六边形架构中 端口和适配器的思想。 6.通过事件来解耦,使用观察者模式来解耦。 7.使用从外而内的设计,让我们更能渐进、流畅的写出符合目标的代码,也更易于使用设计原则与设计模式。 8.将原来零散的知识,内聚起来,向上抽象出一个层次。例如:高质量测试、代码评审、结对编程、静态扫描工具,都是为了提高代码质量;重构、测试驱动开发、持续集成,都是为了使软件持续演进。 代码整洁之道中提到,Michael Feathers说整洁的代码总是看起来像是某位特别在意它的人写的。书中提到很多开发实践中的原则和技巧,负责和用心的态度也很重要。实现有价值的目标,并且在实现这一目标的过程中能享受其中。追寻达成目标需要很多次的实践。
走马观花地看了一遍。作者结合自己数十年的经验,进行了结构性的总结和输出,功力深厚,炉火纯青。 从需求,设计,开发,测试等软件全生命周期都有不同侧重的阐述,中间涉及到很多细节,涉猎甚广,如需求金字塔,敏捷开发,整洁架构,DDD,TDD,持续集成。 印象最深的是,代码是负债还是资产?都不是,是期权。 值得一读再读。
需求分析金字塔: 不断质疑,澄清业务目标 探索业务流程,定义系统功能 设计操作步骤,澄清业务规则 不断质疑,澄清业务目标 金字塔的第一层是业务目标,这是所有需求分析和讨论活动的起点。它致力于搞懂需求获取阶段的核心任务:为什么要做这个功能?有时候这个问题还可以反过来:如果不做这个功能,又会怎样?通过这样反复地质疑,往往能把需求背后的思考表达得更为清晰。 业务目标反映了系统的关键利益方(后文统称为业务方)对“通过某个业务过程,达成某种业务目标”的期望,这些业务方往往是业务所有者、项目发起人等。 高校后勤部门是这个项目的发起方,但评价其是否成功的核心指标不是“做出了一个系统”,而是“供应商和大学生都有了更高的满意度”。所以,如何能通过餐品预订提高满意度,是这个项目成功的关键。(如何提升供应商的满意度?供应商现在有哪些不够满意的地方?) 探索业务流程,定义系统功能 金字塔的第二层旨在在功能概要的粒度上解决系统应该实现什么功能这个问题,我们称之为系统功能或系统责任。但是,不应该直接从业务目标跳到系统功能。在系统之外,一些外部系统、各种业务参与者也参与了业务活动,他们之间的交互共同构成了业务流程。 业务流程的设计显然需要服务于业务目标。不过,这个设计往往不是简单地复制现实世界的业务流程。如果发现正在运作的业务流程不合理,就需要探索新的流程方案。因此,这一步的关键是“探索”,而不是“描述”。 在业务流程分析清楚之后,系统功能就变得非常清晰了。系统功能就是业务流程中那些和软件系统有关的功能。例如,前述的发红包业务的管理员设定红包发放对象、为红包发放对象发红包等功能,都是在金字塔的这一层进行探索的结果。 业务流程聚焦于业务活动中的主体如何通过一系列业务活动交互,最终达成业务目标。业务交互的主体,也就是参与者,既包含特定的业务角色,如食堂餐品管理员、订餐人,也包含系统以及外部系统等。系统功能是整个业务流程的一部分。 业务流程的设计可以有多种方法,正向的设计思路比较自然,也就是从同学浏览餐品和下单开始,到最终取到餐品结束。从前向后符合人类的思考习惯,不过这不见得是最好的探索与发现方案。经验表明:正向的思考过程往往容易遗漏关键步骤。 EDBA的核心成功要素是:以业务事件为核心、以终为始、逆向思考。通过使用EDBA,我们能更容易地发现合理的业务流程,避免遗漏关键问题。 业务事件指的是应该被关心的、具有业务价值的事件。基于业务事件进行讨论,可以让需求讨论更聚焦、更清晰。这是因为事件实际发生了,才是业务流程的真正目标。只要事件没发生,业务流程就没有实际意义。相反,事件发生了,那相应的活动反而是可以变通的。 事件优先,由后向前,关注例外,整理推演。方法有效原因: . 如何聚焦讨论:业务事件把讨论聚焦到结果和实际发生的事情这样具有确定性的内容上。 .如何推导:通过逆向思考,让流程设计在思考的过程中自然浮现。 .关注异常:异常是导致结果不能达成的一个因素,通过在早期发现异常场景,并予以正确应对,有助于业务流程设计的完整性。 .延迟决策:业务流程需要我们暂时忘记系统,首先关注事件。系统功能的设计是业务流程设计完成后自然而然就可以推演出来的。 从业务流程到系统需求 系统需求是把“软件系统”作为研究对象,定义软件系统应该做什么,确定清晰的输入和输出。 用例(use case),顾名思义就是“谁使用系统做什么”。用例是一种非常有效的用来表达系统需求的方法 业务流程的关注点是业务,系统用例的关注点则要低一个层级,它关注系统。业务流程是分析系统用例时的输入,基于这两个业务流程,就可以提取出系统用例。 设计操作步骤,澄清业务规则 金字塔的最下面一层关注的是需求的细节:具体的操作步骤和业务规则。例如,前述的设定红包发放对象选择规则等具体的步骤和规则,都是在这一层进行探索的结果。 越往金字塔的下层,细节越多,对于讨论的清晰程度的挑战就越大。当然,越往金字塔的上层,细节虽然越少,但是一旦发生错误,影响是最大的。 需求分析的过程,是一个持续探索和发现的过程。这个过程应该遵循金字塔结构,由粗到细,逐层展开。 细节包括两个重要部分。 .操作步骤:完成一个任务需要执行的步骤。在我们的案例中,可能需要执行的步骤包括添加食品到购物车、确定取餐时间、选择取餐点、确认订单等。 .业务规则:从业务视角出发的行为约束。在我们的案例中,可能会约定取餐时间不是任意选择的,而是以15分钟为一个时间单位,且仅覆盖就餐时间。 领域驱动设计 战术模式包括三方面内容: .基本构造块。领域驱动设计定义了四种构造块:实体、值对象、领域服务和领域事件。这些构造块是表达业务概念的基本元素,8.2节将会对它们展开介绍。 .业务完整性的单元。类和对象的粒度很细。领域驱动设计提出了聚合这个关键概念 4,把面向对象设计的粒度从基本构造块提升到了能真正表达业务意义的层次。基于聚合,领域驱动设计还定义了资源库和工厂,这两个模式分别用于管理聚合的存取和创建。8.3节将介绍聚合、资源库和工厂。 .分层架构。领域模型不应该“淹没”在频繁变化的业务逻辑中。所以,领域驱动设计提出了四层分层架构,特别突出了领域层。在此基础上,又发展出了一系列变体,包括六边形架构、整洁架构等。8.4节将介绍分层架构和相关概念,以及如何基于分层架构完成代码实现。 4领域驱动设计中的聚合和UML中的聚合概念有所不同,请读者注意区分。 领域驱动设计的战略模式定义了限界上下文(Bounded Context),用来表达架构层次上的边界。显然,在理想情况下,限界上下文的边界和子域的边界应该保持一致。 既然进行了划分,就需要考虑集成的问题。不同场景下的集成策略有所不同,领域驱动设计总结了一个很全面的集成策略,就是上下文映射。我们将在8.5节和8.6节讨论限界上下文和上下文映射的问题。 只有在确实表达了一个相对独立的业务概念或者业务策略,并且不能简单地把它归结到某个既有的业务对象上时,才是一个真正的领域服务。 由于领域服务不持有数据,所以它自身是没有状态的。对软件实现来说,无状态是一件好事。 领域事件是一种特殊的值对象,代表从业务专家视角看到的某种重要的事情发生了。事件机制是实现开放 - 封闭原则的重要手段。 在分布式系统中,领域事件往往还需要一个全局唯一的ID,来实现事件的可追踪、防止重复等。 紧密相关的对象存在数据一致性问题。聚合用边界把这些紧密相关的对象放到了一起,保证业务完整性。 (1) 生命周期一致性;(2) 问题域一致性;(3) 尽量小的聚合。 小聚合之间的协作 读写模型分离是一种有效的架构策略,可以大幅改善查询性能。其基本示意图如图8.8所示。它把数据的存储模型分为读模型和写模型。其中,写模型面向领域模型定义,读模型面向查询场景定义。 . 接口层负责处理跟边界相关的部分。 .应用层负责处理业务逻辑,业务逻辑是变化较为频繁的。 .领域层负责处理领域模型和领域逻辑,领域模型稳定且接近业务本质,是最为重要的一层。 .基础设施层负责处理数据库、消息等系统运行时所必须的基础设施。 如同细胞,限界上下文本质上是一个自治的小世界,它有完备的职责,还有清晰的边界。
本书对于刚开始进行 ai coding 没有开发经验的群体十分有价值, 系统的对开发原则,思路,最近实践进行讲解, 解答了我在做 ai coding 过程中遇到的一些困惑 1,先开发前端,还是后端, 先做规划,设计业务逻辑图,前端框架,在进行开发 2,为什么总是开发到一半想重头开发 在项目开始阶段没有对需求完整的思考清晰 3,ai 说开发完了,一测试好多问题 没有设计测试用例,和成功标准
非常不错的一本书,系统性的梳理了高质量的软件设计如何实践。这书就像一本大纲,可以依据书中的实践原则进行拓展学习,值得反复阅读理解。