《代码大全》笔记 —— 模块六:系统化考虑

程序规模对架构的影响

  • 随着项目规模的扩大,沟通交流也需要有保障。大多数方法论的要点在于减少沟通问题,而一个方法论的存亡也取决于它是否能够有效地促进沟通。
  • 其他所有条件都等同的情况下,大项目的生产率将低于小项目。
  • 其他所有条件都等同的情况下,大项目的每千行代码错误率高于小项目。
  • 在小项目中一些看起来理所当然的活动,在大型项目中则必须认真规划。随着项目规模的扩大,构建活动越来越不占主导。
  • 与缩减 “重量级” 方法论相比,对 “轻量级” 方法论进行扩充往往效果更佳。在所有方法论当中,最有效的当属 “适量级” 方法论。

组织架构则需要解决沟通的复杂性。

沟通和规模

精简化沟通所采取的典型方法是在文件中把它正式化。不是让 50 个人以各种可以想象的组合互相交谈,而是让 50 个人阅读和撰写文件。

项目规模和范围

思考项目规模的一种方式是思考项目团队的规模。

项目规模对错误的影响

无论错误的数量还是类型都受项目规模的影响。

错误的数量随着项目规模的扩大而急剧增加,非常大的项目每千行代码的错误数量达到了小项目的四倍。

项目规模对生产力的影响

小项目的生产力可能是大项目的两道三倍,而且从最小到最大的项目,生产力可能相差五到十倍。

项目规模对开发活动的影响

更微妙的影响是最终软件的质量和复杂性。

要协调的人越多,协调他们需要的正式文档越多。

管理构建

  • 良好的编码实践可通过强制的标准或更宽松的方法来实现。
  • 如应用得当,配置管理(尤其是变更控制)能使程序员的工作变得更容易。
  • 好的软件评估是一项重大的挑战。成功的关键在于采用多种方法,随着项目的开展调整评估,并利用之前确定的数据来创建新的评估。
  • 构建管理要取得成功,度量是关键。项目的任何方面都可以找到一些方法进行度量,这比根本不测量要好。为了实现准确的进度表、质量控制和改善开发过程,准确的度量是关键。
  • 程序员和管理者都是人,以人为本并善待他们,让他们取得更好的绩效。

鼓励良好的编码实践

一般来说,从管理岗位强制要求一套严格的技术标准并不是一个好主意。

如果项目中要有定义标准,请让一个受人尊敬的架构师来定义。(标准不是红线,不能严格执行,推荐最优。)

灵活的指导原则、一系列建议而不是指导原则或者一组体现最佳实践的例子。

  1. 逐行评审代码
  2. 要求代码签核
  3. 选取优秀的代码示例作参考
  4. 重点强调代码是公有财产(最少团队内公开)
  5. 奖励好的代码
  6. 一个简单的标准

配置管理

配置管理是指标识出项目工件并以系统化的方式处理变更,使项目能随时间的推移保持其完整性。评估提议的变更请求、追踪变更、保留系统在不同时间点的多个历史版本。(对需求、变更、代码管理)

SCM 关注系统的需求、源代码、文档和测试数据。使不确定变得更加确定,方向明确。

解决该问题的一个办法是先记录所有想法和建议,无论它们实现起来有多容易。做好记录,直到有时间才处理。

提防大量的变更请求。变更较多,则可能存在问题,非最好设计。

成立变更控制委员会或适合自己项目的类似组织。

变更控制往往会滋生官僚主义,所以,重要的是想办法简化变更控制过程。

版本控制软件:代码版本、发布版本。

备份计划是定期备份自己的工作(更多属于组织效能)。

评估构建进度表

检查得越细致,评估结构越准确。

采用多种评估方法并比较结果。定期重新评估。

对软件项目进度影响最大的就是程序的规模。

一旦确定交付日期和产品规范,剩下的主要问题就是如何控制好人员和技术资源的开销,以便能够按时交付产品。

项目并不能在后期把时间补回来,而是越来越落后。

扩充团队。

缩减项目范围。如去掉一项特性,也就消除了相应的设计、编码、调试、测试和文档工作,同时也移除了该特性和其他特性之间的接口。

如果做不到完整移除某项特征,可提供该相同功能的简化版本,或许还可以按时交付一个尚未进行性能调优的版本。最不重要的功能可以实现得相当粗略。(提供简易版本或缩减项目)

度量

留意度量的副作用。度量具有激励作用。人们倾向于关注那些被度量的工作,忽略那些没有的。

子程序中异常度量数据是一个警告信号,表明应重新检查该子程序,找出质量出乎寻常偏低的原因。

以人为本,善待每一位程序员

一个程序员大约有 30% 的时间花在对项目并没有直接助益的非技术活动智商:步行和个人事务等。

向上管理

以下为向上管理的一些方法:

  • 向其植入自己的想法和创意,等着管理者来一场头脑风暴(其实就是你的意思),跟你讨论你本来就想做的事情。
  • 将正确的做事方式教给管理者。这是一项需要持之以恒的工作,因为管理者经常会被提升、调动或解聘。
  • 关注管理者的兴趣,按他们真正想要的方式做事,不要让他们注意到不必要的实现细节,想象成对个人工作的一种 “封装”。
  • 拒绝按管理者说的做,坚决用正确的方法做事。
  • 另外找份工作。

集成

集成作为一种软件开发活动,是指将多个单独软件组件整合成一个系统。

  • 构建顺序和集成方法可以影响类的设计、编码和测试顺序。
  • 经过深思熟虑的集成顺序可以减少测试工作并使调试变得更容易。
  • 增量式集成有多种策略,除非项目规模极小,否则其中任何一种增量式集成都优于阶段式集成。
  • 对于任何特定的项目,最好的集成方法通常是组合了自顶向下、自底向上、面向风险和其他集成方法的混合方法。T 型集成垂直切片集成是两种通常很奏效的方法。
  • 每日构建可以减少集成问题,提高开发人员的士气,提供有用的项目管理信息。

集成的频率,阶段式还是增量式

阶段式集成:(“大爆炸式集成”)

  1. 设计、编码、测试和调试每个类。这一步称为 “单元开发”。
  2. 将这些类合并成一个大的系统。这一步称为系统集成。
  3. 测试和调试整个系统。这就是所谓的 “系统崩溃”。

增量式集成:(“滚雪球式集成”)

  1. 开发系统的一小部分功能。
  2. 设计、编码、测试和调试类。
  3. 将新构建的类与骨架进行集成。

增量式集成的优点:

  • 更容易定位错误
  • 系统在项目早期就获得成功
  • 获得进展监控
  • 改善客户关系
  • 可以用更短的开发进度来完成系统构建

增量式集成策略

必须更细致地规划组件构建的顺序。

根据具体情况选择更为合适的集成方式,也可各种组合。

自顶向下集成

  • 在自顶向下集成中,系统中层次构建顶部的类需要先写,然后再集成。(简单描述:先 mock 的方式跑起来,再逐步将 mock 解决掉跑起来。)
  • 自顶向下集成的额外优势是系统的控制逻辑能够得到相对较早的测试。非常有助于快速暴露出大型的、概念性的设计问题。
  • 垂直切片:分功能进行垂直切片。

自底向上集成

  • 在自底向上集成的方法里,系统中层次结构底部的类先编写并集成。一次集成只添加一个类而不是一次性在集成中添加所有的低层类,自底向上集成成为一种增量式集成策略。
  • 将可能的错误源限制为集成的单个类,因此很容易定位错误。
  • 主要问题是该方法将主要的、高层的系统接口的集成留到最后。

三明治集成

  • 先集成层次结构中的顶层类和被广泛使用的底层类,再集成中间层的类。
  • 在系统层次结构的顶部集成高层级业务对象类。然后在层次结构的底部集成接口类以及被广泛使用的通用功能类。

面向风险的集成

  • 面向风险的集成也被称为 “困难部分优先集成”。(哪部分最不可控则优先集成哪部分。)

面向特性的集成

  • 和垂直切分很像,知识每次集成粒度变大到特性。

T 形集成

  • 构建并集成了系统的一个深层的垂直切片部分来验证整个系统的架构性假设,然后横向构建并拓展系统的整体宽度,为开发其余功能提供一个框架结构。

每次构建和冒烟测试

感知是否有质量降低风险:通过每天对所有代码进行冒烟测试,可以防止质量问题对项目的恶劣影响。

需根据集成单次时长,来选择对应的集成频率(分为构建与部署频率、测试频率)。

实现每日构建和冒烟测试的自动化。

早上发版(早上构建版本):相比晚上不那么降低士气(不会逼迫大家被迫加班),并且更方便找到开发人员。

一定频率被称为持续。持续很多时候表示 “至少达到每天的频率”。