智能推荐系统项目正式启动了。小明拉团队开会,问"推荐系统要做什么",十个人给了十种答案。产品经理说"要像抖音一样上瘾",技术说"要搞深度学习",运营说"要把客单价提上去"。小明意识到:大家连"问题是什么"都没搞清楚,就开始说"怎么做了"。
架构设计师的看家本领就是系统分析与设计——先搞清问题,再画蓝图。本章就是这门手艺的完整修炼手册。
🔍 8.1.1 问题分析:搞清"到底要解决什么"
目标:在开发之前对要解决的问题有更透彻的理解。五步走:
| 步骤 | 干什么 | 关键工具 |
|---|---|---|
| 1. 达成共识 | 把问题写出来,获得大家认可。要素:问题概述/影响/结果/优点 | UP的问题陈述格式 |
| 2. 理解本质 | 透过表面找根源 | 因果鱼骨图 + 帕累托图 |
| 3. 确定干系人 | 谁受系统影响?谁是用户/客户?谁评估?谁维护? | — |
| 4. 定义系统边界 | 系统和现实世界的分界线在哪? | 上下文范围图(DFD顶层) / 用例模型 |
| 5. 确定约束 | 进度/投资收益/人员/设备预算/环境/OS/数据库/已有软件等限制 | — |
因果鱼骨图:把问题写在右边方框,确定潜在原因大类连到脊骨,头脑风暴找原因归类。帕累托图:直方图按频率从高到低排列,帮找"关键的20%原因造成80%问题"。
📋 8.1.2 问题定义:目标+功能需求+非功能需求
问题分析完,综合定义三方面:
1. 目标:构建系统的原因,最高层次的用户需求。描述注意:优势(不只解决问题还提供业务优势)、度量(有衡量标准)、合理性(工作量<业务优势)、可行性、可达成性。
2. 功能需求:系统必须做的事,源于业务需求,只与问题域相关。注意详细程度和二义性——同名异义词、代词指代不明。检查二义性的有效方法:大声朗读出来,大家一起边听边讨论。
3. 非功能需求:系统必须具备的属性,不改变功能而是为工作赋予特征。思维模式:功能需求以动词为特征,非功能需求以副词为特征。
| 非功能需求 | 说明 |
|---|---|
| 观感需求 | 界面外观的精神实质 |
| 易用性需求 | 接受率、生产效率、错误率、特殊人群可用性 |
| 性能需求 | 速度/精度/安全性/容量/吞吐量/可靠性/可用性/可扩展性 |
| 可操作性 | 操作环境 |
| 可维护性/可移植性 | 期望的改变及允许时间 |
| 安全性 | 保密性/完整性/可获得性 |
| 文化政策/法律 | 适用法律和标准 |
📊 8.2.1 需求分析:74%的失败项目的一半栽在这
Standish Group调研23000个项目:28%彻底失败,46%超预算或超工期,仅26%成功。失败项目中约60%源于需求问题——差不多一半的项目都遇到了需求问题。
需求分析四方面工作:
- 🔍 问题识别:发现描述需求(功能/性能/环境/可靠性/安全保密/用户界面/资源/成本进度)
- 🔀 分析与综合:反复分析整合解决方案。方法:SA(结构化分析)、Jackson、OOA、状态迁移图、Petri网
- 📄 编制文档:需求规格说明书
- ✅ 评审:正确性/完整性/清晰性
需求分类:功能需求(必须做的事)+ 非功能需求(必须具备的属性)+ 设计约束(限制条件,如必须用国产数据库、必须UNIX下运行)。另外三个层次:业务需求(组织高层目标)→ 用户需求(用户要完成的任务)→ 系统需求(系统角度的功能/质量/约束)。
需求工程=需求开发(捕获→分析→编写规格→验证4阶段)+ 需求管理(基线/变更/跟踪)。开发是主线是目标,管理是支持是保障。
需求分析方法演进:结构化分析(SA, Tom DeMarco)→软系统方法(Checkland, 过渡性)→面向对象分析(OOA)→面向问题域分析(PDOA)。
🎨 8.2.2-8.2.3 系统设计:选择与妥协的艺术
需求分析解决"做什么",系统设计解决"怎么做"。设计者的难题:在功能、性能、健壮性、开发周期、交付日期等矛盾目标间找到平衡点。
设计分两阶段:概要设计(高层设计,需求→数据结构和系统结构,划分模块确定关系)+ 详细设计(低层设计,细化结构表示,数据结构与算法)。
设计方法比较:结构化方法侧重"模块相对独立且功能单一";Jackson方法从数据结构导出模块结构;Parnas方法将可能变化因素隐藏在模块内部。现代主流=对象技术(高内聚低耦合)。
📐 8.3.1 结构化分析:数据流图的天下
结构化分析(SA)=面向数据流的需求分析方法。核心思想:自顶向下逐层分解。把大问题分解成小问题,小问题再分解,直到最底层足够简单。
SA工具箱:数据流图(DFD) + 数据字典(DD) + 结构化语言 + 判定表 + 判定树。
SA工作三步:① 研究"物质环境"(画当前系统DFD,含部门名/岗位名/报表名)→ ② 建立逻辑模型(转成等价逻辑流)→ ③ 划清人机界限(确定哪些自动化哪些手工)。
DFD五元素:
- ⚙️ 过程(加工):输入到输出的转换
- 👤 外部实体(源/宿):系统外的数据源或目的
- 💾 数据存储(文件):存放数据的地方
- ➡️ 数据流:从一处到另一处的流向
- 🔗 实时连接:过程执行时外部实体与过程的来回通信
DFD层次:Context图(最高层,整个系统=一个过程,所有外部实体和数据流)→ DFD 0层图(分解过程0)→ DFD 1层图(分解1/2/3号过程,编号1.1/1.2...)→ 逐级分解。关键:0层图的输入输出必须与Context图完全一致。
数据字典:对DFD部件的精确描述。符号:=(由…构成)、+(和)、[ | ](或)、{ }(n次重复)、( )(可选)、*…*(注释)。
🏗️ 8.3.2 结构化设计:从DFD到结构图
结构化设计(SD)=面向数据流的设计,以SA成果为基础,自顶而下、逐步求精、模块化。包括架构设计、接口设计、数据设计和过程设计。
结构图三成分:模块、调用(模块间调用关系)、数据(传递及处理的数据信息)。
DFD中信息流分两种:
- 🔄 变换流:信息经输入通路→变换中心处理→输出通路离开
- 🔀 事务流:信息进入后,事务中心根据类型选若干动作序列之一执行
详细设计工具:程序流程图(简单直观但随意性大,容易画成非结构化)、盒图(符合结构化原则,功能域明确,无法任意转移控制,但修改困难)、PAD(符合自顶向下逐步求精,最大特点=方便转为源代码)、PDL/伪码(形式化语言,控制结构确定但内部描述语法不确定,不可执行)。
🧩 8.3.3 模块设计:高内聚低耦合
模块化=分而治之,使程序结构清晰、易于测试与修改。两大原则:信息隐蔽 + 模块独立。
信息隐蔽:每个成分封装在单一模块中,尽可能少暴露内部处理。将难的决策、可能修改的决策、数据结构内部连接、硬件有关细节等隐蔽起来。提高可修改性、可测试性、可移植性。
模块独立用耦合(模块间联系紧密程度,越低越好)和内聚(模块内元素联系紧密程度,越高越好)衡量:
| 耦合(越低越好) | 内聚(越高越好) |
|---|---|
| 非直接(最好) | 功能(最好) |
| 数据 | 顺序 |
| 标记 | 通信 |
| 控制 | 过程 |
| 通信 | 时间内聚 |
| 公共 | 逻辑 |
| 内容(最差) | 偶然(最差) |
其他模块设计注意:大小适中、减少调用深度、单入口单出口、作用域在控制域之内、功能可预测。
🎯 8.4.1 面向对象基本概念:对象、类、继承、多态
对象=标识(名称)+属性(状态)+服务(操作),封装为整体以接口对外提供服务。类=对具有相同属性和服务的一组对象的抽象。类分三种:
- 📦 实体类:映射需求中的实体,保存持久信息。一定有属性,不一定有操作。如学员类、课程类。参与者一般对应实体类。
- ⚙️ 控制类:控制用例工作的类,动宾短语转化来的名词。没有属性,一定有方法。如"身份验证器"。
- 🔌 边界类:封装用例内外流动的信息,位于系统与外界交接处(窗体/报表/接口/协议)。可既有属性又有方法。
继承与泛化:子类从父类继承,泛化是父类对子类的关系(一对多)。
多态:一般类定义的属性/服务被特殊类继承后可表现不同行为。4种形式:参数多态、包含多态(通用多态)+ 重载多态、强制多态(特定多态)。重载=编译时执行(静态绑定),改写=运行时选择(动态绑定)。
模板类(类属类):实现参数多态,抽象与类型无关部分,用变元表示与类型有关部分。
消息通信:对象间唯一合法的动态联系途径,与封装原则密不可分。
📖 8.4.2 面向对象分析方法:四大流派
| 方法 | 提出者 | 特点 |
|---|---|---|
| OOA/OOD | Coad & Yourdon | 5层次(主题/对象类/结构/属性/服务),OOD 4部件(问题域/人机交互/任务管理/数据管理) |
| Booch | Booch | 螺旋上升,宏过程+微过程,4步(标识类对象/确定含义/标识关系/说明接口和实现) |
| OMT | Rumbaugh | 三模型:对象模型(类图)+动态模型(状态图)+功能模型(数据流图) |
| OOSE | Jacobson | 在OMT基础上提出"用例"概念,取代数据流图做需求分析 |
OMT、OOSE、Booch最终统一成为UML。
📐 8.4.3 UML:统一建模语言
UML将OMT、OOSE和Booch融合,是国际统一的软件建模标准。不仅是OO建模,还可用于工作流、业务领域。
UML结构三部分:
- 构造块:建模元素(结构事物:类/接口/协作/用例/活动类/组件/节点;行为事物:交互/状态机;分组事物:包;注释事物)+ 关系(关联/依赖/泛化/实现)+ 图(UML 2.0共14种图)
- 公共机制:规格说明、修饰、公共分类(类元与实体/接口与实现)、扩展机制(约束/构造型/标记值)
- 架构:5个系统视图——逻辑视图、进程视图、实现视图、部署视图、用例视图
14种图分两类:静态模型(类图/对象图/包图/构件图/部署图/制品图)+ 动态模型(用例图/顺序图/通信图/定时图/状态图/活动图/交互概览图,对象图跨两类)。
用例图核心概念:参与者(与系统接口的任何事物或人,虚拟角色)、用例(系统行为的动态描述,给参与者可见价值)、包含关系<<include>>(提取公共行为=抽象用例)、扩展关系<<extend>>(分离不同场景)。
类图——OO方法的核心。类的三格表示:类名/属性/操作。属性语法:可见性 属性名:类型=默认值{约束},可见性 +(public)/-(private)/#(protected)。
类间4种关系:
| 关系 | 说明 | UML表示 |
|---|---|---|
| 依赖 | 改X可能引起改Y | 带箭头虚线 |
| 泛化 | 父类与子类 | 带空心箭头实线→父类 |
| 关联 | 语义上的联系(最通用最弱) | 实线 |
| 实现 | 接口与实现类/组件 | 带空心箭头虚线 |
聚合 vs 组合(都是特殊的关联):聚合=整体与部分,生命周期可不同(车和车轮),空心菱形→整体;组合=整体与部分生命周期相同(公司和部门),实心菱形→整体。
多重性:n…m,n=最少,m=最多(不确切用*)。常见:0…1、0…*、1…1、1…*、*。
交互图三兄弟:顺序图(强调时间顺序)、通信图(协作图,强调静态链接关系)、定时图(强调时间约束,UML 2.0新增,坐标轴交换、生命线凹凸表示状态、有时间刻度标尺)。
状态图:描述特定对象所有可能状态及转移。初始状态(实心圆,只一个)、结束状态(实心圆外套空心圆,可多个)、状态转移(箭头+事件)。
活动图:由状态图变化而来,一个活动结束立即进入下一个。引入判定(菱形)、分支与组合(粗线)、泳道(活动由谁完成)、对象流、信号。
构件图:源代码/二进制/可执行文件间的依赖关系。部署图:硬件物理拓扑结构+软件部署。节点(立方体)、连接(通信路径)、构件(可执行代码模块)、接口(小圆圈直线)。
🖥️ 8.5 用户界面设计:三个黄金法则
Theo Mandel总结三大黄金法则:
- 👤 置用户于控制之下:不强迫进入不必要动作、提供灵活交互、允许中断和撤销、随技能增长流水化、隔离技术细节、允许直接交互
- 🧠 减少用户记忆负担:减少短期记忆要求、建立有意义的默认、直觉性捷径、基于真实世界隐喻、渐进式提示
- 🔄 保持界面一致:允许放入有意义语境、应用系列内保持一致、不要随意改变已建立的用户期望
界面设计4个框架活动:用户/任务/环境分析→界面设计→实现→界面确认(迭代)。
🔄 8.6 工作流设计:让流程跑起来
工作流=能完全或部分自动执行的经营过程,根据过程规则在执行者间传递文档/信息/任务。流程设计的主要困难=现实复杂性——所有流程模型都是对现实的简化,计算机只根据确定信息判断,现实中有大量不确定性。
核心概念:工作流(现实过程的抽象)、流程定义(形式化表示)、流程实例(运行实例)、工作流管理系统(存储定义+触发状态改变+推动流程)、流程定义工具、参与者(谁)、活动(做什么)、活动所有者(谁决定结束)、工作所有者(谁控制整体)、工作项。
WFMC参考模型=6个基本模块:
- 🖌️ 流程定义工具:设计者抽象流程→转为形式化语言
- ⚙️ 工作流执行服务:核心,解释流程定义、激活实例、推动运转、维护活动列表、可邮件/短信提醒
- 🔗 其他工作流执行服务:多个系统间有效交互,避免信息孤岛
- 👤 客户应用程序:给最终用户的界面,处理数据、推动活动
- 📞 被调用应用程序:处理工作流所携带数据(如电子文档处理)
- 📊 管理和监控工具:状态查询、挂起、恢复、销毁、运行统计
🌐 8.7 分布式计算机应用系统设计
单台计算机功能有限,联网协同可完成更复杂任务。分布式协作两种方式:
| 协作方式 | 特点 | 适用 |
|---|---|---|
| 基于实例的协作 | 实例地位相同,可远程创建/调用/销毁对象。用"代理"模式 | 小范围网络良好环境(近连接) |
| 基于服务的协作 | 只提供接口,不远程创建/销毁对象。分层结构 | 跨平台、网络响应慢(远连接) |
分布式系统倾向大粒度设计——一个方法包含多参数、代表独立功能,减少网络调用次数。单系统内细粒度无所谓,但分布式每次方法调用都是网络通信。
💻 8.8 系统运行环境集成与设计
软件运行环境=设备+操作系统+网络配置。几种典型环境:
- 🏛️ 集中式系统:所有操作集中于一台主机。组成:单计算机结构(简单但受限)、集群结构(类似平台负载均衡)、多计算机结构(不同环境,适合可分解子系统)。银行/保险/证券常用,现代通常是分布式的一个环节。
- 🌐 分布式系统:基于网络(局域网/广域网),多种形式
- 🔗 C/S结构:服务器提供服务+客户机请求接受结果
- 🏗️ 多层结构:数据层+逻辑层+视图层(三层),复杂可增层。需要中间件(管件)实现层间通信
- 🌍 Internet/Intranet/Extranet:Internet=全球TCP/IP网络;Intranet=私有内部网;Extranet=扩展的Intranet含合作企业。Web基于C/S结构,优势=标准+广泛存在+费用低,劣势=安全性+可靠性
🔀 8.9 系统过渡计划:新旧系统怎么交接
新系统取代旧系统时的三种过渡方式:
| 方式 | 做法 | 风险 | 成本 |
|---|---|---|---|
| 直接过渡 | 新系统运行时立即关闭旧系统 | 高 | 低 |
| 并行过渡 | 新旧同时运行一段时间 | 低 | 高(2.5-3倍) |
| 阶段过渡 | 分步骤逐步切换 | 中 | 中 |
老王感慨:"分析和设计做好了,开发就是水到渠成。"但小明知道:系统分析和设计只是架构师能力的开始——第9章的软件架构设计才是架构设计师的真正主场。