《软件设计从专业到卓越》笔记

《软件设计从专业到卓越》作者张刚是软件工程博士、资深技术专家、CCF软件工程委员会执行委员,作者有20余年软件开发、架构设计和技术领导者的成功经验,他是先进软件工程方法与实践的持续探索者和积极传播者。

作者将精益编程实践总结为上图:

  • 一个根本挑战:软件与生俱来的复杂性
  • 两大核心价值:软件开发的当前业务价值(满足业务需求)和长期资产价值(复用和演进)
  • 三大设计原则:分而治之、持续演进和质量内建

我等手机厂商软件工程师,基于Android系统或芯片厂商代码开发特性或增强特性,对软件复杂性的体会比互联网公司更为深刻。企业受市场压力优先寻求业务价值是可以理解的,有远见的业务主管同时会舍得在长期资产价值方面投入,因为这是未来高效高质实现业务价值的关键因素之一。实现长期资产价值需要实践高质量需求分析、领域建模、测试先行、持续演进。

本书覆盖了软件设计技术提升的3个层次:

  • 品味篇:从价值和特征角度,辨别什么是好的设计,
  • 专业篇:提升专业素养,包括提炼高质量需求、建立领域模型、高质量完成设计分解和依赖管理,
  • 卓越篇:高效编程的关键,讲解了测试先行、由外而内、演进式设计等现代软件设计实践。

全部内容几乎都在服务质量内建的目标,设计质量贯穿始终。没有人会认为质量不重要,但实际情况下,在项目进度的压力之下,牺牲质量,特别是牺牲外部看不到的可理解、可演进和可复用能力,是不少开发者和开发团队下意识的选择。这种做法本质上是饮鸩止渴,也是没有深入理解软件开发的一种表现。质量内建意味着质量来自持续改进的生产过程,而不是检验。

下面分享一些重点内容:

1. 品味篇-识别优秀设计

优质代码的外部特征:(1)实现了期望的功能,(2)缺陷尽量少,(3)易于理解,(4)易于演进,(5)易于复用。

软件解决的现实世界的复杂问题,所以开发软件的过程是一个持续建立认知的过程。我们不能希望一开始就对问题有直达本质的认知,随着开发过程的展开,渐渐地弄明白问题是很正常的。

缺陷不可能完全避免,要规避缺陷造成的影响,最重要的原则是尽量早地发现缺陷。降低缺陷的发现和修复成本的有效办法是:全面自动化、更小的迭代。

优质代码的内部特征:

(1)一致的编码风格, (2)有意义的命名, (3)简洁的行为实现, (4)高内聚和低耦合的模块化结构, (5)没有重复, (6)没有多余的设, (7)具备自动化测试。

2. 专业篇-建立扎实功底

高质量的需求,事件风暴的发明人Alberto Brandolini有一句很精确的表述:是程序员的理解,而不是产品经理的设计,成为系统最后的功能。共创、沟通和共识是需求分析活动成功的关键。在协作空间中,需要需求相关人员、开发人员、测试人员等不同角色共同参与需求分析,这样有助于得到高质量的分析结果。

结构化的需求探索:需求分析的金字塔,形象地表达了由粗到细、逐步展开的需求分析过程。第一层是业务目标,通过不断质疑澄清业务目标;第二层在功能概要的粒度上解决系统应该实现什么功能。金字塔越往下层,细节越多,对于讨论的清晰程序挑战就越大。表达业务流程使用自然语言不利于高效沟通,需要引入UML,使用带泳道的活动图来表达业务流程,要能充分反映关键的业务节点,不要陷入操作细节。从业务流程到系统需求可以用用例图,用例图表达执行者、系统用例、系统边界之间关系的UML图。第三层设计操作步骤,澄清业务规则,要使用实例而不是抽象概念,用Given-When-Then模式。

领域模型是高质量软件开发和持续演进的基础。领域模型是深层模型,是在业务演进过程中持续加深认知的结果,它沉淀了关键的业务知识。作者提到领域建模的常见误区有:(1)避免从开发视角进行领域建模,领域模型一定要站在业务视角看(2)避免建立庞大的领域模型,把大领域拆分为小的子域,并为每个子域分别建模(3)避免只是重视文档,而忽略交流和共识。领域模型一定要显式化,如果没有显式化,没有把领域模型写下来,没有形成在团队中口口相传的知识,这种模型就并不是真正存在的。在大多数场景下,UML类图是表达领域模型的合适选择,作者重点讲解了常见的关系:关联、多重性、聚合和组合、泛化、依赖。要注意UML类图并不是领域模型,领域模型是认知本身,我们要根据场景选用恰当的工具。

软件设计的本质是设计分解和责任分配,就是模块化。分而治之是控制软件复杂性的有效手段。架构分解的三个原则:(1)优先按照问题领域分解,(2)面向质量属性定义架构策略,(3)选用合适的架构风格和模式。风格和模式是既往设计经验的结晶,架构模式有很多,但基本思路都是"上下文-问题-解决方案“。要成为卓越的设计师,就需要广泛地阅读,学习前人的设计经验,在内心建立丰富的模式库,并将模式灵活运用于实际工作中。正确使用语言特性,委托是一种非常强大的复用方式。用设计模式指导软件设计。

依赖设计的基本原则:依赖最小化原则和稳定依赖原则。显式地区分需求方接口和提供方接口,并且定义清晰的接口契约,是提升软件独立演进能力和复用能力的关键,作者给出详细的讲解和代码示例。SOLID原则虽然不全面,但它易于理解和传播。

3. 卓越篇-实现高效编码

契约显式化是测试先行的本质,测试先行使测试的本质不是”发现错误“质量保证,而是定义契约。自动化测试是活文档,只有文档和代码建立关联,才能保证让文档得持续更新。

领域驱动设计包括两组模式:战术模式和战略模式。其中,战术模式关注具体的软件实现方法,战略模式重点关注大粒度的业务架构和服务划分。统一语言是为了尽量缩小问题域和实现域的表示差距,增强可理解性,同时保持领域模型的持续演进。领域驱动设计的四层架构是:接口层——>应用层——>领域层——>基础设施层。

  • 接口层负责处理跟边界相关的部分。
  • 应用层负责处理业务逻辑,业务逻辑是变化较为频繁的。
  • 领域层负责处理领域模型和领域逻辑,领域模型稳定且接近业务本质,是最为重要的一层。
  • 基础设施层负责处理数据库、消息等系统运行时所必须的基础设施。

代码目录结构: 

—— main 
   |__ java 
       |__ com.project.sample 
           |—— interfaces 
           |—— application 
           |—— domain 
           |__ infrastructure

由外而内的设计也叫意图导向的编程。它是提升软件设计效率的法宝。作者通过演示案例,展示了由外而内如何和设计契约、测试先行、测试替身、设计模式和设计原则相结合地实践应用。

“戴明质量管理十四条”说:不能依靠检验来达到质量标准。质量内建使得缺陷在注入时刻就被发现,从而降低了由缺陷导致的成本。I模型的本质就是质量内建,由于质量保证活动和自动化测试贯穿了需求、架构、设计和编码的各个阶段,所以问题会在注入的第一时间就被发现。

I模型推导出的实践有三个特点:

  • 在需求阶段立即验证需求质量,实例化需求
  • 在设计阶段立即验证设计质量,测试驱动开发
  • 在编码阶段立即验证编码质量,结对编程

质量内建意味着组织和职能的变革,对自动化测试有很高的要求。针对自动化测试的反模式,大家总结了若干原则,其中比较有名的是FIRST原则:

  • Fast:运行必须快速
  • Independent:让每个测试尽量保持独立
  • Repeatable:可重复的测试
  • Self Validating:自动化测试意味着自我验证
  • Timely:自动化测试必及时编写

明智地应用度量指标,度量不是目的,用尽量少的指标撬动尽可能大的质量改进行动,带来更好的设计结果,才是我们追求的真正目标。要持续地对度量进行监控,因为软件具有天然腐化的趋势,“熵增原理”,就是封闭系统的混乱度一定会逐步上升。在没有刻意提升质量的情况下,软件的设计质量一定会逐步下降。

重构是演进式设计的发动机,能够驱动设计演进的进程。要警惕破窗效应,用代码坏味道作为重构信号。

精益思想的五大原则:

  • 价值:从客户视角定义价值,而不是从生产者的立场出发
  • 价值流:关心价值生产过程中的所有活动,价值流图是精益管理方法中的常用工具之一
  • 流动:要让增值活动在价值流上顺畅流动
  • 拉动:从最末端的用户需求开始,逐步倒推到生产的每个步骤,从而实现高质量的协同
  • 持续改进:对于复杂系统,在一开始就把一切都规划好是不现实的,需要在实践中持续思考当前的方法,持续地追求尽善尽美

书中作者给出具体案例和关键代码片段,除了系统介绍软件工程方法,还具有较强的实践指导价值。

  • 30
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值