第8章 · 趣味学习

系统分析与设计:从"搞清问题"到"画出蓝图"

智能推荐系统项目正式启动了。小明拉团队开会,问"推荐系统要做什么",十个人给了十种答案。产品经理说"要像抖音一样上瘾",技术说"要搞深度学习",运营说"要把客单价提上去"。小明意识到:大家连"问题是什么"都没搞清楚,就开始说"怎么做了"

架构设计师的看家本领就是系统分析与设计——先搞清问题,再画蓝图。本章就是这门手艺的完整修炼手册。

🔍 8.1.1 问题分析:搞清"到底要解决什么"

目标:在开发之前对要解决的问题有更透彻的理解。五步走:

步骤 干什么 关键工具
1. 达成共识把问题写出来,获得大家认可。要素:问题概述/影响/结果/优点UP的问题陈述格式
2. 理解本质透过表面找根源因果鱼骨图 + 帕累托图
3. 确定干系人谁受系统影响?谁是用户/客户?谁评估?谁维护?
4. 定义系统边界系统和现实世界的分界线在哪?上下文范围图(DFD顶层) / 用例模型
5. 确定约束进度/投资收益/人员/设备预算/环境/OS/数据库/已有软件等限制

因果鱼骨图:把问题写在右边方框,确定潜在原因大类连到脊骨,头脑风暴找原因归类。帕累托图:直方图按频率从高到低排列,帮找"关键的20%原因造成80%问题"。

鱼骨图像"破案"——被害人(问题)在右边,大骨头是嫌疑大类(人/机/料/法/环),小骨头是具体嫌疑人。帕累托图像"报警排行"——80%的报修来自20%的问题,先治最严重的。

📋 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/OODCoad & Yourdon5层次(主题/对象类/结构/属性/服务),OOD 4部件(问题域/人机交互/任务管理/数据管理)
BoochBooch螺旋上升,宏过程+微过程,4步(标识类对象/确定含义/标识关系/说明接口和实现)
OMTRumbaugh三模型:对象模型(类图)+动态模型(状态图)+功能模型(数据流图)
OOSEJacobson在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新增,坐标轴交换、生命线凹凸表示状态、有时间刻度标尺)。

状态图:描述特定对象所有可能状态及转移。初始状态(实心圆,只一个)、结束状态(实心圆外套空心圆,可多个)、状态转移(箭头+事件)。

活动图:由状态图变化而来,一个活动结束立即进入下一个。引入判定(菱形)、分支与组合(粗线)、泳道(活动由谁完成)、对象流信号

构件图:源代码/二进制/可执行文件间的依赖关系。部署图:硬件物理拓扑结构+软件部署。节点(立方体)、连接(通信路径)、构件(可执行代码模块)、接口(小圆圈直线)。

💡 秒懂技巧:UML 14种图记不住?分三类背——结构图看"长什么样"(类图/对象图/构件图/部署图/包图/制品图),行为图看"做什么"(用例图/活动图/状态图),交互图看"怎么交互"(顺序图/通信图/定时图/交互概览图)。聚合组合区别记:聚合"可拆"(车轮可换),组合"不可拆"(部门随公司存亡)。

🖥️ 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倍)
阶段过渡分步骤逐步切换
🎮 实战场景:饿了么么推荐系统上线——核心推荐功能先直接过渡(能容忍短暂停机),支付等关键链路并行过渡(新老同时跑一周验证),供应链平台阶段过渡(一个模块一个模块切换)。
🎬 故事结局:小明带着团队完成了推荐系统的完整分析设计——用鱼骨图找到推荐效果差的根本原因,用DFD画清楚数据流向,用UML类图设计了推荐引擎的类结构,用活动图画了用户下单→推荐→成交的完整流程。界面设计遵循三大黄金法则,工作流引擎推动审批流程,分布式大粒度设计减少网络调用。系统平稳上线,转化率提升了8%。

老王感慨:"分析和设计做好了,开发就是水到渠成。"但小明知道:系统分析和设计只是架构师能力的开始——第9章的软件架构设计才是架构设计师的真正主场。