软件架构课程第3讲:David Parnas 经典论文精读

课程:0B105 软件体系结构(北京大学软件与微电子学院) 讲师:周立新博士 文件:03parnas.ppt(55.50KB,PowerPoint 97-2003 格式) 主题:Parnas 三篇经典论文导读

一、软件设计方法演进简史

年代方法代表核心思想
1960s结构化编程Dijkstra “Goto Considered Harmful”从形式化语义和程序证明出发,用结构化控制流替代 goto
1970s结构化设计—将程序划分为子程序的方法论和指导方针
1980s模块化(基于对象)编程Ada / Modula / Euclid子程序与数据封装为模块
1990s面向对象语言与 OOA/OOD—面向对象分析与设计提供指导

注:Parnas 的工作横跨 1970s,是从结构化设计走向模块化/面向对象的关键桥梁人物。


二、Parnas 三篇经典论文

David Parnas 是软件工程领域的先驱,其三篇经典论文奠定了模块化设计、软件架构和产品线工程的理论基础:

论文 1:《论系统分解为模块的准则》(1972)

  • 出处:Comm. ACM 15, 12 (Dec. 1972), 1053-1058
  • 核心议题:模块化(modularization)
  • 模块定义:一组子程序和数据元素的集合
  • 历史地位:对过程式设计的批判,指向基于对象和面向对象设计的方向
  • 经典案例:KWIC(Key Word in Context,上下文关键词索引)程序的两种模块化方式

KWIC 系统简介

KWIC 系统接受若干行文本作为输入,输出所有关键词(每个词作为首词)的字母排序列表。例如:

输入:Designing Software for Ease of Construction
输出:
  Construction Designing Software for Ease of
  Designing Software for Ease of Construction
  Ease of Construction Designing Software for
  for Ease of Construction Designing Software
  of Construction Designing Software for Ease
  Software for Ease of Construction Designing

模块化方案一:按处理步骤划分

每个主要处理步骤是一个模块:

  1. 输入(Input) — 读取输入
  2. 循环移位(Circular Shift) — 生成所有循环移位
  3. 字母排序(Alphabetizer) — 按字母排序
  4. 输出(Output) — 输出结果

这是典型的流水线/过程式分解思路。

模块化方案二:按信息隐藏划分

每个模块拥有一个或多个”秘密”(secrets):

  • Lines — 隐藏字符/行的存储方式
  • Circular Shifter — 隐藏移位算法和移位结果的存储
  • Alphabetizer — 隐藏排序算法和排序策略(如是否懒惰排序)

这是**信息隐藏(Information Hiding)**原则的首次系统阐述。


两种模块化方式的比较

总体比较

  • 两种系统可能共享相同的数据结构和相同的算法
  • 差异在于工作分配的划分方式
  • 即使运行时表示完全相同,系统在本质上也可能截然不同
  • 因为运行时表示仅用于”运行”,其他表示还用于:
    • 修改(Changing)
    • 文档编写(Documenting)
    • 理解(Understanding)
    • ……

可变性比较(Changeability)

可能变化的设计决策模块化1受影响模块数模块化2受影响模块数
输入格式11
所有行存储在内存中all1
字符打包存储(4个/字)all1
用索引表示循环移位而非存储31
排序策略(一次排序 vs 搜索 vs 混合)31

信息隐藏模块化在应对设计决策变化时,受影响的模块数显著更少。

独立开发比较(Independent Development)

维度模块化1模块化2
并行开发前提必须先设计所有数据结构必须先设计接口
描述复杂度需要复杂的描述只需简单的接口描述

可理解性比较(Comprehensibility)

  • Parnas 的主观判断:模块化2 更优
  • 信息隐藏让每个模块可以独立理解,不需要了解其他模块的内部实现

论文 2:《论一个流行词:层次结构》(1974)

  • 出处:IFIP Congress ‘74, North Holland Publishing Company, 1974, pp. 336-339
  • 历史地位:最早对后来被称为”软件架构”的领域进行抽象讨论
  • 核心论点:批驳”层次化 = 好”的流行观念,指出”层次”一词被用于多种不同含义,且经常被混用
  • 背景:操作系统设计语境,对比 T.H.E、MULTICS、RC4000 三大系统

层次结构的五种类型

  1. 程序层次(Program Hierarchy)

    • 调用层次(calls hierarchy)
    • 仅在人类处理系统时有意义
    • 例:内联函数在语义上等价于函数调用
  2. 进程层次(Process Hierarchy)

    • 经常与其他层次混淆
    • 例:T.H.E 系统中的”分配工作”关系
  3. 资源分配层次(Resource Allocation Hierarchy)

    • 例:RC4000 系统
  4. 保护层次(Protection Hierarchy)

    • 例:MULTICS 系统
  5. 模块层次(Module Hierarchy)

    • 过程或模块是更高层模块的一部分

关键洞见:五种层次结构经常被混为一谈,但它们本质上是不同的。好的设计需要明确区分这些不同类型的层次关系。


论文 3:《论程序族的设计与开发》(1976)

  • 出处:IEEE Trans. On SE., vol. SE-2, pp. 1-9, Mar. 1976
  • 核心概念:程序族(Family of Programs)
  • 核心思想:
    • 当值得研究时,先研究共同属性
    • 再确定每个族成员的特殊属性
  • 历史地位:以下领域的理论基础:
    • 面向变化的设计(Designing for change)
    • 复用库(Reuse libraries)
    • 面向对象设计(OO Design)

开发方法

经典方法:顺序完成(Sequential completion)

  • 先完整开发族中的一个成员
  • 修改得到下一个
  • 依此类推

新技术(Parnas 提出):

  • 开发到一个中间阶段
  • 不同的族成员从中间阶段开始做出不同的设计决策
  • 必须表示中间阶段

两种实现路径:

  1. 基于逐步精化(Stepwise refinement based)

    • 推迟操作数类型和运算符的实现到后期
  2. 基于模块(Module based)

    • 指定模块接口
    • 替换不同的实现

三、核心洞见总结

  1. 信息隐藏是模块化的黄金准则 — 模块应以”设计决策秘密”为边界,而非以处理步骤为边界
  2. 层次不等于好 — “层次结构”有多种含义(程序/进程/资源/保护/模块),不可笼统推崇
  3. 程序族思想是产品线工程的源头 — 先提取共性,再分别定制,这比逐个开发效率高得多
  4. 运行时表示 ≠ 全部 — 软件还有修改、文档、理解等维度,模块化的价值在这些维度中体现

四、关联知识


本笔记由 PPT 二进制文件解析提取文本后整理而成,原文为英文课件。