用户界面软件架构的设计空间与设计规则
CMU/SEI-90-TR-22 | ESD-90-TR-223 | Thomas G. Lane | November 1990 CMU School of Computer Science / Software Engineering Institute 软件架构设计原则项目(Software Architecture Design Principles Project)
一、核心贡献
本报告是 Thomas G. Lane 博士论文 Lane 90a(https://…) 的总结版,提出了一套用户界面软件架构的多维设计空间(design space)和基于该空间的设计规则(design rules),将软件工程知识以结构化方式编码,用于支持”常规设计”(routine design)。
两大核心概念:
- 设计空间:用近 50 个维度对用户界面系统架构进行分类,每个维度代表一个系统特征或设计选择
- 设计规则:描述维度之间的相关性,即哪些设计选择组合是合适的/不合适的
配套报告 CMU/SEI-90-TR-18 论证了设计空间与设计规则方法可能是表达软件工程知识的一种广泛适用的手段 Lane 90b。
二、为什么需要设计空间:常规设计 vs 创新设计
2.1 工程领域的两类设计方法
| 类别 | 特点 | 成本 | 可靠性 |
|---|---|---|---|
| 常规设计(Routine Design) | 用标准化方法解决已知类型问题 | 低,设计工作量最小 | 高,经过充分验证 |
| 创新设计(Innovative Design) | 从抽象原则出发发明新方案 | 高,试错成本大 | 低,更可能失败 |
工程手册(handbook)的主要目的就是支持常规设计——给用户提供标准设计方法及其优缺点的知识。
2.2 软件工程的现状
- 算法和数据结构领域已有”手册式”文本(Knuth、Sedgewick)
- 软件架构层面尚无此类手册
- 设计师要么从零开始发明,要么不管适用性如何重复使用熟悉的设计
- 本报告是在用户界面系统这一有限领域内,构建软件系统架构常规实践的起点
2.3 设计空间的本质价值
“The design space is useful in its own right as a shared vocabulary for describing and understanding systems.”
- 作为描述和理解系统的共享词汇表
- 发现维度间的相关性(correlations),形成设计规则
- 成功的系统设计在空间中呈现聚类(clustering),失败的区域则是空白
- 需求维度 + 结构维度 → 设计规则直接给出设计指导
三、基本结构模型(三组件划分)
任何完整的用户界面系统可分为三部分:
┌─────────────────────────────────┐
│ Application-Specific Code │ ← 应用特有代码
│ (特定应用的功能核心 + UI代码) │
├─────────────────────────────────┤ ← 应用接口(Application Interface)
│ Shared User Interface Code │ ← 共享用户界面代码
│ (支持多应用,适用于所有设备) │
├─────────────────────────────────┤ ← 设备接口(Device Interface)
│ Device-Dependent Code │ ← 设备相关代码
│ (特定 I/O 设备类) │
└─────────────────────────────────┘
两个关键划分接口:
- 应用接口(application interface):应用特有代码 vs 共享 UI 代码
- 设备接口(device interface):共享 UI 代码 vs 设备相关代码
分析不同层次时可以重新定义标签。例如分析 X Window 时,可以把服务器外部都视为应用特有,再把服务器分为共享 UI 层和设备相关层。
四、功能设计维度(Functional Dimensions)
功能维度描述系统需求,是结构设计之前的规格说明。报告将其分为三大组:外部需求、基本交互行为、实践考量。
4.1 最重要的 5 个功能维度
基于自动化设计规则实验中的权重排序,对结构影响最大的 5 个维度全部与灵活性相关:
- 用户界面系统跨设备适应性(User interface system adaptability across devices)
- 应用跨设备可移植性(Application portability across devices)
- 应用跨交互风格可移植性(Application portability across interaction styles)
- 基本界面类别(Basic interface class)
- 系统组织方式(System organization)
洞见:系统所需适应性的性质和程度,是决定合适架构的最重要因素。这一特性是用户界面系统结构独有,还是对其他软件也成立,仍是开放问题。
接下来 5 个重要维度:
- 可用处理能力
- I/O 设备类别广度
- 用户界面系统跨交互风格适应性
- 用户可定制性
- 外部事件处理
4.2 关键功能维度详解
命令执行时间(Command Execution Time)
- 短:所有命令零点几秒内完成 → 可不需要异步输入处理
- 中等(平均短):大多很快,部分几秒 → 需要 type-ahead
- 长:用户明显感知等待 → 需要取消、进度反馈
外部事件处理(External Event Handling)
- 无:应用只在特定命令时检查外部事件
- 等待输入时处理:响应外部事件但不抢占用户命令
- 抢占用户命令:外部事件优先级足够高,必须中断当前命令
跨设备适应性(UI Adaptability Across Devices)
- 无:所有设备行为完全一致
- 局部行为变化:菜单外观等小细节变化
- 全局行为变化:界面风格级别的重大变化(如菜单驱动 vs 命令语言)
- 应用语义变化:命令底层语义改变(如连续显示 vs 命令式显示)
基本界面类别(Basic Interface Class)
Shneiderman 分类法:
- 菜单选择(Menu selection)
- 表单填充(Form filling)
- 命令语言(Command language)
- 自然语言(Natural language)
- 直接操纵(Direct manipulation)
菜单和表单可用相似结构支持,其他各类各有独特要求。
五、结构设计维度(Structural Dimensions)
结构维度是决定系统整体架构的主要决策。分为三大组:功能与知识划分、表示问题、控制流与同步。
5.1 应用接口抽象级别(6 层)
这是最关键的结构维度,按通信抽象程度从低到高:
| 级别 | 类型 | 特点 | 典型例子 |
|---|---|---|---|
| 1 | 单体程序(Monolithic program) | 无分离,应用完全控制 UI | 视频游戏 |
| 2 | 抽象设备(Abstract device) | 共享代码只是设备驱动,提供物理操作(画线条),应用控制全部交互行为 | 键盘/显示驱动的字符回显 |
| 3 | 工具包(Toolkit) | 共享代码提供交互技术库(菜单、滚动条),应用负责选择和组合,全局行为仍由应用控制 | Xt、Motif |
| 4 | 固定数据类型交互管理器(IM with fixed data types) | 共享代码控制局部和全局交互序列,通信用标准数据类型(整型、字符串) | 典型 UIMS |
| 5 | 可扩展数据类型交互管理器(IM with extensible data types) | 同上,但数据类型集合可扩展,应用指定新类型的输入输出转换 | 高级 UIMS |
| 6 | 可扩展交互管理器(Extensible interaction manager) | 应用提供代码来增强或覆盖交互管理器的内部操作(通常通过面向对象继承) | 面向对象 UI 框架 |
各层适用场景与代价:
- 单体程序:小型专用系统,需要大量 UI 细节控制且处理能力有限时适用。有任何灵活性需求(用户定制、设备变化、风格灵活性)时不要选。
- 抽象设备:需要跨有限设备的应用可移植性,但 UI 控制权主要在应用手中。不适合跨 UI 风格的高可移植性需求。
- 工具包:节省应用开发工作量,同时保留系统灵活性(应用仍”说了算”,必要时可绕过工具包)。要实现标准化 UI 风格,这是最低抽象级别。
- 交互管理器(IM):当应用可移植性(跨设备或风格)是强需求时的好选择,因为它提供 UI 行为与应用程序的强分离。但难以支持直接操纵(因为应用无法提供语义反馈)。
- 可扩展数据类型 IM:允许表示转换与应用主体完全分离,但对语义反馈问题帮助不大,灵活性增量有限。
- 可扩展 IM:灵活性最高(用户定制、设备变化、UI 风格),可用于直接操纵(通过定制能力)。但需要大量处理能力,初始投资最高,且容易破坏应用与 UI 的逻辑分离。
关键观察:构建比抽象设备更复杂的东西的收益,很大程度上取决于 UI 行为标准化的程度——即系统环境中 UI 惯例的强度。惯例越强,越能把功能放进工具包或 IM。
5.2 抽象设备可变性(4 种)
设备接口定义了设备无关代码操作的抽象设备。按设备无关代码感知的可变性程度分类:
| 类型 | 特点 | 适用场景 | 例子 |
|---|---|---|---|
| 理想设备(Ideal device) | 所有设备可变性对上层隐藏;真实设备应接近理想模型 | 设备差异小,或差异不需要 UI 行为重思考 | PostScript 成像模型 |
| 参数化设备(Parameterized device) | 设备类别广,差异通过参数表达(屏幕大小、颜色数、鼠标按键数);上层可查询参数并适应 | 需要支持广泛设备,且需要全局 UI 行为变化 | X Window 图形模型 |
| 可变操作设备(Device with variable operations) | 操作集合定义良好,但设备驱动在实现上有相当自由度;上层不关心精确外部行为 | 操作抽象级别足够高,驱动有大量自由;不适合直接操纵 | GKS 逻辑输入设备、Scribe 排版模型 |
| Ad-hoc 设备 | 抽象设备定义是临时拼凑的,行为因设备而异 | 几乎从不适合新设计,主要存在于从简单系统演化来的系统 | 字母数字终端 |
选择原则:
- 预期设备变化小 → 理想设备模型(无运行时开销,定义清晰)
- 需要广泛设备支持且需全局行为变化 → 参数化(但应用端 case 分析成本高)
- 中等局部变化 + 可接受放弃 UI 细节控制 → 可变操作(处理能力需求低)
- 参数化 + 可变操作可以组合(简单应用用驱动默认,复杂应用自行决策)
5.3 表示问题(Representation Issues)
UI 定义表示法(6 种)
| 类型 | 灵活性 | 易用性 | 用户定制 | 处理能力需求 |
|---|---|---|---|---|
| 共享 UI 代码中隐式 | 最低 | - | 否 | 最低 |
| 应用代码中隐式 | 高 | - | 否 | 低 |
| 外部声明式 | 低 | 最高 | 支持 | 高(除非预编译) |
| 内部声明式 | 低 | 高 | 难 | 中 |
| 外部过程式 | 高 | 较低 | 支持(高级用户) | 高 |
| 内部过程式 | 最高 | 较低 | 否 | 低 |
经验法则:
- 静态信息或有限选择 → 声明式表示
- 动态行为 → 过程式表示
- 需要用户定制 → 外部表示
- 否则 → 内部表示(更简单高效)
- 只有效率关键或变化概率极低时 → 隐式表示
5.4 控制流与同步
应用控制流
- 单输入点(Single input point):适合”无模式”界面,解耦应用与 UI 序列细节,高可移植性/用户定制性倾向于单输入点
- 多输入点(Multiple input point):应用动作不需要与用户交互原子化时才使用
控制线程数
- 单线程:简单系统足够,外部事件或长命令不适合
- 一个 UI 线程 + 一个应用线程:非常流行,解耦 UI 控制流与应用
- 多 UI 线程:处理逻辑独立的并行交互(无模式界面、多输入设备)
- 多应用线程:处理外部事件,或用于取消用户命令
如果有廉价的线程机制,除最简单 UI 外都应该用双线程方法。
异步输入处理
- 忽略:最简单,但长命令时不可用
- 全部排队后处理:事件不滞留队列时好,长命令不可用(缺反馈)
- 部分处理 + 排队:最灵活,但需要多线程且引入同步问题
一般原则:用尽可能不灵活的方法。
六、设计规则方法:从设计空间到设计指导
6.1 设计规则的本质
设计规则描述维度之间的相关性——哪些选择组合是合适的,哪些不合适。
发现方法:观察成功系统在设计空间中的聚类分布,空白区域通常代表不好的设计。
6.2 自动化设计规则(第 4 章)
Lane 实验了用自动化方法从设计空间数据中生成设计规则:
- 对功能维度按其对结构维度的影响力排序(如前面”最重要的 5 个维度”)
- 实验显示这些规则未能完全复现人类专家的决策
- 但提供了洞见:适应性维度是结构的最重要决定因素
6.3 关键设计规则精选
应用接口抽象级别选择规则:
- 有任何强灵活性需求(用户定制/设备变化/UI 风格灵活)→ 不要选单体程序
- 跨 UI 风格的应用可移植性是强需求 → 抽象设备不是好选择
- 要实现标准化 UI 风格 → 至少用工具包级别
- 应用可移植性是强需求 → 交互管理器(IM)好选择
- 直接操纵界面 → IM 难以支持(除非是可扩展 IM)
- 网络环境 → IM 特别适合(可物理分离,通信成本低)
- UI 惯例强度高 → 倾向工具包和可扩展 IM,再倾向非扩展 IM
抽象设备可变性选择规则:
- 预期设备变化小 → 理想设备
- 需要广泛设备 + 全局行为变化 → 参数化
- 中等局部变化 + 可接受放弃 UI 细节控制 → 可变操作
- 应用可移植性至关重要 → 参数化方法风险高(应用可能未覆盖全部参数变化)
表示法选择规则:
- 静态信息/有限选择 → 声明式
- 动态行为 → 过程式
- 需要用户定制 → 外部表示
- 效率关键或极少变化 → 隐式表示
控制流选择规则:
- 高可移植性或用户定制性 → 单输入点控制流
- 外部事件需抢占 → 需要抢占式调度的线程机制
- 有廉价线程机制 → 除最简单 UI 外都用双线程
七、设计空间方法的更广泛意义
7.1 与建筑类比
Shaw Shaw 89 指出大规模系统需要更高级别的抽象。设计空间方法正是提供这样的高级抽象——不是具体设计,而是设计选择的分类体系和决策规则。
7.2 软件工程知识的编码化
本报告的方法论意义(见配套报告 Lane 90b):
- 设计空间 + 设计规则 = 一种表达软件工程知识的系统方法
- 类似于传统工程的手册,但形式化程度更高
- 可作为常规设计的基础,减少重复造轮子
- 为设计知识的积累和传承提供结构化框架
7.3 局限性
- 当前局限于用户界面系统这一特定领域
- 维度分类粒度需要实践验证
- 自动化设计规则尚未达到人类专家水平
- 设计空间方法是否适用于更广泛的软件类别,仍是开放问题
八、与其他知识的关联
- 设计空间与设计规则 — 软件架构系统研究方法(tr18.90.pdf,姊妹篇,方法论视角)
- 《结构化计算机组成》— Tanenbaum 的 6 层抽象模型可视为硬件领域的设计空间
- 《代码整洁之道》— 编程层面的”常规设计”手册(等价于算法/数据结构层面的 handbook)
- 《敏捷软件开发》— 设计原则(SOLID 等)本质上也是设计规则的一种形式
- Mary Shaw 的软件架构工作 — Lane 的理论基础来源之一
- Seeheim Workshop(1983)— UIMS 的早期经典研讨会,Tanner & Buxton 报告
关键概念速查
| 概念 | 一句话解释 |
|---|---|
| Design Space | 多维分类体系,每个维度代表一个设计选择 |
| Design Rule | 维度间的相关性,指导合适的设计组合 |
| Routine Design | 用标准化方法解决已知问题,低成本高可靠 |
| Application Interface | 应用代码与共享 UI 代码的分界线 |
| Device Interface | 共享 UI 代码与设备相关代码的分界线 |
| Abstraction Level | 应用接口的 6 层抽象(单体→可扩展 IM) |
| Abstract Device Variability | 设备接口的 4 种可变性模型 |
| Control Thread | 独立执行和等待事件的逻辑实体(比 process 更广义) |