软件架构设计温昱第二版.pdf
http://www.100md.com
2021年1月27日
![]() |
| 第1页 |
![]() |
| 第7页 |
![]() |
| 第19页 |
![]() |
| 第21页 |
![]() |
| 第32页 |
![]() |
| 第189页 |
参见附件(29145KB,370页)。
软件架构设计温昱第二版
本书对于有志于成为架构师的程序员们具有非常有效的指导意义,对于已经成为架构师的同行们系统化规范架构设计也是一本很好的教材。感兴趣的欢迎阅读学习

内容简介
本书围绕“软件架构设计”主题,从“程序员”成长的视角,深入浅出地讲述了架构师的修炼之道。从“基础篇”、到“设计过程篇”、到“模块划分专题”,本书覆盖了架构设计的关键技能项,并且对于架构设计过程中可能出现的各种问题给与了解答。
本书对于有志于成为架构师的程序员们具有非常有效的指导意义,对于已经成为架构师的同行们系统化规范架构设计也是一本很好的教材。
相关内容部分预览








作者简介
温昱资深咨询顾问,软件架构专家。软件架构思想的传播者和积极推动者,中国软件技术大会杰出贡献专家。十五年系统规划、架构设计和研发管理经验,在金融、航空、多媒体、电信、中间件平台等领域负责和参与多个大型系统的规划、设计、开发与管理。
目 录
第1章 从程序员到架构师
1.1 软件业人才结构
1.1.1 金字塔型,还是橄榄型?
1.1.2 从程序员向架构师转型
1.2 本书价值
1.2.1 阅读路径1:架构设计入门
1.2.2 阅读路径2:领会大系统架构设计
1.2.3 阅读路径3:从需求到架构的全过程
1.2.4 阅读路径4:结合工作,解决实际问题
第1部分 基本概念篇
第2章 解析软件架构概念
第3章 理解架构设计视图
第2部分 实践过程篇
第4章 架构设计过程
第5章 需求分析
第6章 用例与需求
第7章 领域建模
第8章 确定关键需求
第9章 概念架构设计
第10章 细化架构设计
第11章 架构验证
第3部分 模块划分专题
第12章 粗粒度“功能模块”划分
第13章 如何分层
第14章 用例驱动的模块划分过程
第15章 模块划分的4步骤方法——运用层、模块、功能 模块、用例驱动
10 个常见的软件架构
有没有想过如何设计大型企业及系统?在开发之前,我们必须要选择一个合适的架构,以保证我们软件的功能和质量。今天就简单介绍一下常用的 10 个架构。
什么是架构?
一直以来,在软件行业,对于什么是架构,都有很多的争论,每个人都有自己的理解。甚至于很多架构师一说架构,就开始谈论什么应用架构、硬件架构、数据架构等等。
我曾经也到处寻找过架构的定义,请教过很多人,结果发现,没有大家都认可的定义。套用一句关于 big data 流行的笑话,放在架构上也适用:
Architecture is like teenage sex,everybody talks about it,nobody really knows what is it。
事实上,架构在软件发明时的 N 多年以前,就已经存在了,这个词最早是跟随着建筑出现的。在软件工程中,架构以理解为:
根据要解决的问题,对目标系统的边界进行界定。
并对目标系统按某个原则的进行切分。切分的原则,要便于不同的角色,对切分出来的部分,并行或串行开展工作,一般并行才能减少时间。
并对这些切分出来的部分,设立沟通机制。
根据 3,使得这些部分之间能够进行有机的联系,合并组装成为一个整体,完成目标系统的所有工作。
(上面关于什么是架构摘自 InfoQ,资深架构师王概凯 Kevin 的专栏)
这篇文章将简述常见的 10 种架构模式的概念、用法以及其优缺点。
分层模式 (Layered pattern)
客户端/服务器模式 (Client-server pattern)
主/从模式 (Master-slave pattern)
管道/过滤器模式 (Pipe-filter pattern)
代理模式 (Broker pattern)
对等模式 (Peer-to-peer pattern)
事件总线模式 (Event-bus pattern)
模型/视图/控制器 (MVC) 模式 (Model-view-controller pattern)
黑板模式 (Blackboard pattern)
解析器模式 (Interpreter pattern)
1. 分层模式 (Layered pattern)
分层模式用于对结构化设计的软件进行层次拆解,每个层次为独立的抽象,为其上层抽象提供服务。
系统通常被拆分为以下四个层次:
表示层(也称为 UI 层)
应用层(也称为服务层)
业务逻辑层(也称为领域层)
数据访问层(也称为持久化层)
使用场景
通用桌面应用程序
电子商务 Web 应用
2. 客户端/服务器模式 (Client-server pattern)
客户端/服务器模式由两个部分构成:一个服务器与多个客户端。服务器组件同时为多个客户端组件提供服务。客户端向服务器发启服务请求,服务器将相应服务信息回应给客户端。此外,服务器持续监听来自客户端的请求。
使用场景
电子邮件、文件共享及银行业务等在线应用
3. 主/从模式 (Master-slave pattern)
主/从模式由两个部分构成:主设备与从设备。主服务组件将作业分发给多个从设备组件,并根据这些从设备反馈的结果,计算生成最终结果。
使用场景
数据库复制,主数据库被认定为权威数据源,各从数据库与主数据保持同步
在计算机系统中通过总线互连的各设备(包括主设备与从设备)
4. 管道/过滤器模式 (Pipe-filter pattern)
管道/过滤器模式用于构造用于生成及处理数据流的系统。每个处理过程都封装在过滤器(filter)组件之中,要处理的数据通过 管道(pips) 进行投递。管道同时用于作为 过滤器(filter) 间的缓冲及同步。
使用场景
编译器,一系列的过滤器用于词法分析、语法分析、语义分析及代码生成
生物信息学的工作流
5. 代理模式(Broker pattern)
代理模式用于在结构化系统中对组件解耦。系统内各组件间采用远过程调用(remote service invocations)的方式交互。代理(Broker)组件充当组件间通讯的协调角色。
提供服务的组件将其能力(服务以及特性)发布给代理,客户端均向代理请求服务,由代理将请求重定向到先前已发布过对应服务的组件进行处理。
使用场景
消息中间件软件:Apache ActiveMQ,Apache Kafka,RabbitMQ 与 JBoss 等等
6. 对等模式 (Peer-to-peer pattern)
对等模式中的组件称之为对等体(peer),对等体既作为向其他对等体请求服务的客户端,同时也做为响应其他对等体请求的服务端。对等体可以在运行过程中动态地改变其角色,即,既可以单独做为客户端或服务端运行,又可同时作为客户端与服务端运行。
使用场景
网络文件共享:Gnutella 与 G2)
流媒体协议:P2PTV 与 PDTP.
流媒体应用: Spotify.
7. 事件总线模式(Event-bus pattern)
事件总线模式应用于事件处理,主要由四个组件构成:事件源(event source),事件侦听者(event listener),通道(Channel)以及总线(event bus)。 事件源将消息发布到总线的特定通道,侦听者订阅相应的通道,事件源所发布的消息经通道通告给订阅通道的侦听者。
使用场景
Android 开发
通告(Notification)服务
8. 模型/视图/控制器 (MVC) 模式(Model-view-controller pattern)
模型/视图/控制器模式(简称 MVC 模式)将交互式应用程序拆分为三个部分:
模型(model) – 包含核心功能及数据
视图(view) – 呈现信息给用户(通过有多个视图)
控制器(controller) – 处理用户的输入操作
MVC 模式通过将内部信息表示、用户信息呈现以及用户操作接收分开的方式解耦组件,实现高效代码重用。
使用场景
主流开发语言所构建的互联网网页应用架构
Django 与 Rails 等网页应用开发框架
9. 黑板模式(Blackboard pattern)
黑板模式适用于 无预知确定解决策略 的问题,主要由三个组件构成:
黑板(blackboard) – 用于存储解空间对象的结构化全局内存
知识(knowledge)源 – 能自表意的专用模块
控制(control)组件 – 选择、配置与执行的模块
所有的组件均能访问黑板,组件可将新生成的数据对象写入黑板,也可以通过模式匹配从黑板中获取知识源所生成的特定数据。
使用场景
语音识别
车辆识别和追踪
蛋白质的结构鉴定
声纳信号解析
10. 解析器模式(Interpreter pattern)
解析器模式用于设计语言的解析程序,主要用于指定评估程序代码行,即解析出特定语言的语句与表达式,其核心思想是为语言的每个符号定义相应的类。
使用场景
SQL 等数据库查询语言
通讯协议描述语言
软件架构设计温昱第二版截图




内容简介
本书围绕“软件架构设计”主题,从“程序员”成长的视角,深
入浅出地讲述了架构师的修炼之道。从“基础篇”、到“设计过程
篇”、到“模块划分专题”,本书覆盖了架构设计的关键技能项,并
且对于架构设计过程中可能出现的各种问题给与了解答。
本书对于有志于成为架构师的程序员们具有非常有效的指导意
义,对于已经成为架构师的同行们系统化规范架构设计也是一本很好
的教材。
未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。
版权所有,侵权必究。
图书在版编目(ClP)数据
软件架构设计:程序员向架构师转型必备温昱著.—2版.—北
京:电子工业出版社,2012.7
ISBN 978-7-121-17087-4
Ⅰ.①软… Ⅱ.①温… Ⅲ.①软件设计-教材 Ⅳ.①TP311.5
中国版本图书馆CIP数据核字(2012)第101071号
责任编辑:孙学瑛
印刷:
装订:
北京中新伟业印刷有限公司
出版发行:电子工业出版社
北京市海淀区万寿路173信箱 邮编100036
开本:787×1092 116 印张:16.5 字数:341千字印次:2012年7月第1次印刷
印数:5000册 定价:39.00元
凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。
若书店售缺,请与本社发行部联系,联系及邮购电话:(010)
88254888。
质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件
至dbqq@phei.com.cn。
服务热线:(010)88258888。Experts Recommend 专家推荐
(以姓氏笔划为序)
与温昱先生初识于一次部门内训,金融机构应用信息技术日久,但业务发展之快仍需信息技术部门不断思索如何提供有力的技术支
持,当时系统设计人员思路难成一致,故邀请先生来讲述所得,先生
讲座生动有趣,案例均为实践中心得,有助于一线设计人员在低头干
事之余,能够抬头看路,从架构高度理解和看待日常工作,《软件架
构设计(第 2 版)》同样着眼于研发实践,不作黄钟大吕之音,而以
一觞一咏畅叙分享一线设计师的感悟体会。此书值得一看,作者亦值
得一晤!
——朱晓光 中国建设银行 北京开发中心 处长
在厦门,曾和温老师有过4天晚上的坐而论道,从技术到业界、从
数据模型到软件重构、从职业观到心理学,彼此颇多启发。第一时间
收到本书的电子版,读来流畅易懂,胜似面晤对谈。本书内容务实、技能梳理清晰,实乃软件开发者职业生涯发展的重要参考。
——朱志 中国建设银行 厦门开发中心总工办
基于软件架构的开发模式,作为软件开发的最佳实践之一,越来
越得到各行各业的重视和关注,但遗憾的是理解其精髓和内涵的人太
少。温老师作为软件架构思想的传播者和推动者,在这本书中,对程
序员如何成长为优秀的架构师给出了非常具体的指导原则和实现方
法,是国内不可多得的真正将软件架构思想阐述如此精准的实践指导
书。作为一名软件行业的从业者,我强烈推荐给大家。
——李哲洙 博士 东软集团 电信事业部 网管产品与系统部部长
这本书以架构设计人员实际工作流程为线索,详细阐述了逻辑架
构和物理架构视图的重要性及其在架构设计中的应用方法。此外,本
书从实践的角度,给出了架构设计的三个原则和 6 大步骤,并以具体
实践过程为指导,给出了架构设计从需求分析到最后的架构设计、架
构验证的完整的架构设计生命周期的实践方法,对软件研发项目团队
和架构师的研发实践工作具有很好的指导意义。——杨勇 中兴通讯 业务研究院 平台总工
从事软件工作近十年,由软件功能模块的程序员开始,到独立负
责几个软件项目的设计开发,一直对软件架构设计比较关注,有幸听
了温昱老师的“软件架构设计”讲座,顿感茅塞顿开,再次阅读温老
师的《软件架构设计》,对架构设计有了更深的感悟。如果你对软件
架构设计感觉朦朦胧胧,温先生的《软件架构设计(第2版)》定能让
你拨开云雾见青天。
——杨为禄 南京国睿安泰信科技股份有限公司 一线软件工程师
近年来,阅读了诸多系统、需求、架构类的书籍资料,温老师的
几本书简明扼要,见解独到,颇多启发。“横看成岭侧成峰,远近高
低各不同”,大系统架构(体系结构)包括系统组分、组分间的关
系,以及演化等三要素;温老师在本书中给出了典型视角、典型模
式、典型过程等实践指南。有志创造系统,赋予软件灵魂的架构师,当读此书。
——张雪松 中国电子科学研究院 复杂大系统研究与仿真
架构是很玄的东西,成为优秀的架构师也是大部分程序员的理
想。温昱先生这本书的特点就是从程序员角度,深入浅出地讲述了架
构师的修炼之道。程序员与架构师区别的最重要一点是看待事物的角
度和处理方法,优秀的程序员按照本书的方法,在日常工作中一步步
实践,有助于培养出架构师的能力,从而逐步成长成为架构师。架构
的目标是为了沟通和交流,温先生也深刻地领悟到这一架构设计的根
本目标,并将这一目标转化为方法论。架构设计不是给自己看的,而
是为了与客户、领导和团队沟通,本书的重点在于架构设计实践,从
用例、需求分析、概念模型、细化模型等一步步地指导如何完成架构
设计,并且对于架构设计过程中可能出现的各种问题给予了解答。本
书对于有志于成为架构师的程序员们具有非常有效的指导意义,对于
已经成为架构师的同行们系统化规范架构设计也是一本很好的教材。
——钱煜明 中兴通讯 业务研究院 移动互联网总工程师
早在2009年的时候就读过温老师的《软件架构设计》第一版,2011年有幸请到温老师来公司主讲“软件架构设计”,幸有当面请教的机会,温老师对软件架构独特的授课方法和深厚的功底让我如沐春
风、豁然开朗,颇有几分“顿悟”之感。
五年磨一剑,如今有幸抢先拜读温老师的《软件架构设计》第二
版,更是被书中内容所折服。书中融合了作者多年来在一线的实践和
培训经验,深入浅出地阐释了什么是软件架构,手把手教你从客户需
求入手顺畅地设计出高可用的软件架构,让你读完本书后情不自禁地
感叹:“原来软件架构设计并没有那么高深莫测!”该书理论和实践
并重,是一本不可多得的软件架构设计的指导书籍。
——崔朝辉 东软集团 技术战略与发展部 资深顾问
站得足够高,才能看得足够远。当今 IT 的架构设计思想理念已
经是经过数次洗礼之后的结晶,而温昱先生抓住了这一结晶生命体的
真正骨架,并深入浅出地汇集成这本书。有了这本书,你就可以依据
自己的Project来高效地添加血肉,构建出独特的有机生命体。
——谌晏生 广州从兴 电力事业部 一线软件设计师作者介绍
温昱 资深咨询顾问,软件架构专家。软件架构思想的传播者和积
极推动者,中国软件技术大会杰出贡献专家。十五年系统规划、架构
设计和研发管理经验,在金融、航空、多媒体、电信、中间件平台等
领域负责和参与多个大型系统的规划、设计、开发与管理。
wy@yupeisoft.com
昱培咨询专注于如下三个领域的咨询与培训:
■ 架构设计
■ 详细设计
training@yupeisoft.com
■ 设计重构
几年来,我们为近百家软企提供了卓有成效的服务。
长期一线经验的积累,更促成了 ADMEMS 架构实践体系、ARCT 设
计重构方法论的形成和成熟,并已成为了我们服务品质的重要保证之
一。目录
Experts Recommend 专家推荐
作者介绍
第1章 从程序员到架构师
1.1 软件业人才结构
1.1.1 金字塔型,还是橄榄型?
1.1.2 从程序员向架构师转型
1.2 本书价值
1.2.1 阅读路径1:架构设计入门
1.2.2 阅读路径2:领会大系统架构设计
1.2.3 阅读路径3:从需求到架构的全过程
1.2.4 阅读路径4:结合工作,解决实际问题
第1部分 基本概念篇
第2章 解析软件架构概念
2.1 软件架构概念的分类
2.1.1 组成派
2.1.2 决策派
2.1.3 软件架构概念大观
2.2 概念思想的解析
2.2.1 软件架构关注分割与交互
2.2.2 软件架构是一系列有层次的决策
2.2.3 系统、子系统、框架都可以有架构
2.3 实际应用(1)——团队对架构看法不一怎么办
2.3.1 结合手上的实际工作来理解架构的含义
2.3.2 这样理解“架构”对吗2.3.3 工作中找答案:先看部分设计
2.3.4 工作中找答案:反观架构概念的体现
第3章 理解架构设计视图
3.1 软件架构为谁而设计
3.1.1 为用户而设计
3.1.2 为客户而设计
3.1.3 为开发人员而设计
3.1.4 为管理人员而设计
3.1.5 总结
3.2 理解架构设计视图
3.2.1 架构视图
3.2.2 一个直观的例子
3.2.3 多组涉众,多个视图
3.3 运用“逻辑视图+物理视图”设计架构
3.3.1 逻辑架构
3.3.2 物理架构
3.3.3 从“逻辑架构+物理架构”到设计实现
3.4 实际应用(2)——开发人员如何快速成长
3.4.1 开发人员应该多尝试设计
3.4.2 实验项目:案例背景、训练目标
3.4.3 逻辑架构设计(迭代1)
3.4.4 物理架构设计(迭代1)
3.4.5 逻辑架构设计(迭代2)
3.4.6 物理架构设计(迭代2)
第2部分 实践过程篇
第4章 架构设计过程
4.1 架构设计的实践脉络
4.1.1 洞察节奏:3个原则4.1.2 掌握过程:6个步骤
4.2 架构设计的速查手册
4.2.1 需求分析
4.2.2 领域建模
4.2.3 确定关键需求
4.2.4 概念架构设计
4.2.5 细化架构设计
4.2.6 架构验证
第5章 需求分析
5.1 需求开发(上)——愿景分析
5.1.1 从概念化阶段说起
5.1.2 愿景
5.1.3 上下文图
5.1.4 愿景分析实践要领
5.2 需求开发(下)——需求分析
5.2.1 需求捕获vs.需求分析vs.系统分析
5.2.2 需求捕获及成果
5.2.3 需求分析及成果
5.2.4 系统分析及成果
5.3 掌握的需求全不全
5.3.1 二维需求观与ADMEMS矩阵
5.3.2 功能
5.3.3 质量
5.3.4 约束
5.4 从需求向设计转化的“密码”
5.4.2 功能:职责协作链
5.4.3 质量:完善驱动力
5.4.4 约束:设计并不自由5.5 实际应用(3)——PM Suite贯穿案例之需求分析
5.5.1 PM Suite案例背景介绍
5.5.2 第1步:明确系统目标
5.5.3 第2步:范围+Feature+上下文图
5.5.4 第3步:画用例图
5.5.5 第4步:写用例规约
5.5.6 插曲:需求启发与需求验证
5.5.7 插曲:非功能需求
5.5.8 《需求规格》与基于ADMEMS矩阵的需求评审
第6章 用例与需求
6.1 用例技术族
6.1.1 用例图
6.1.2 用例简述、用户故事
6.1.3 用例规约
6.1.4 用例实现、鲁棒图
6.1.5 4种技术的关系
6.2 用例技术族的应用场景
6.2.1 用例与需求分析
6.2.2 用例与需求文档
6.2.3 用例与需求变更
6.3 实际应用(4)——用例建模够不够?流程建模要不
要
6.3.1 软件事业部的故事
6.3.2 小型方法:需求分析的三套实践论(上)
6.3.3 中型方法:需求分析的三套实践论(中)
6.3.4 大型方法:需求分析的三套实践论(下)
6.3.5 PM Suite应用一幕
第7章 领域建模7.1 什么是领域模型
7.1.1 领域模型“是什么”
7.1.2 领域模型“什么样”
7.1.3 领域模型“为什么”
7.2 需求人员视角——促进用户沟通、解决分析瘫痪
7.2.1 领域建模与需求分析的关系
7.2.2 沟通不足
7.2.3 分析瘫痪
7.2.4 案例:多步领域建模,熟悉陌生领域
7.3 开发人员视角——破解“领域知识不足”死结
7.3.1 领域模型作为“理解领域的手段”
7.3.2 案例:从词汇表到领域模型
7.4 实际应用(5)——功能决定如何建模,模型决定功
能扩展
7.4.1 案例:模型决定功能扩展
7.4.2 实践:功能决定如何建模
7.4.3 PM Suite领域建模实录(1)——类图
7.4.4 PM Suite领域建模实录(2)——状态图
7.4.5 PM Suite领域建模实录(3)——可扩展性
第8章 确定关键需求
8.1 众说纷纭——什么决定了架构
8.1.1 用例驱动论
8.1.2 质量决定论
8.1.3 经验决定论
8.2 真知灼见——关键需求决定架构
8.2.1 “目标错误”比“遗漏需求”更糟糕
8.2.2 关键需求决定架构,其余需求验证架构
8.3 付诸行动——如何确定关键需求8.3.1 确定关键质量
8.3.2 确定关键功能
8.4 实际应用(6)——小系统与大系统的架构分水岭
8.4.1 架构师的“拿来主义”困惑
8.4.2 场景1:小型PMIS(项目型ISV背景)
8.4.3 场景2:大型PM Suite(产品型ISV背景)
8.4.4 场景3:多个自主产品组成的方案(例如
IBM)
8.4.5 “拿来主义”虽好,但要合适才行
第9章 概念架构设计
9.1 概念架构是什么
9.1.1 概念架构是直指目标的设计思想、重大选择
9.1.2 案例1:汽车电子AUTOSAR——跨平台复用
9.1.3 案例2:腾讯QQvideo架构——高性能
9.1.4 案例3:微软MFC架构——简化开发
9.1.5 总结
9.2 概念架构设计概述
9.2.1 “关键需求”进,“概念架构”出
9.2.2 概念架构≠理想化架构
9.2.3 概念架构≠细化架构
9.3 左手功能——概念架构设计(上)
9.3.1 什么样的鸿沟,架什么样的桥
9.3.2 鲁棒图“是什么”
9.3.3 鲁棒图“画什么”
9.3.4 鲁棒图“怎么画”
9.4 右手质量——概念架构设计(下)
9.4.1 再谈什么样的鸿沟,架什么样的桥
9.4.2 场景思维9.4.3 场景思维的工具
9.4.4 目标—场景—决策表应用举例
9.5 概念架构设计实践要领
9.5.1 要领1:功能需求与质量需求并重
9.5.2 要领2:概念架构设计的1个决定、4个选择
9.5.3 要领3:备选设计
9.6 实际应用(7)——PM Suite贯穿案例之概念架构设
计
9.6.1 第1步:通过初步设计,探索架构风格和高层
分割
9.6.2 第2步:选择架构风格,划分顶级子系统
9.6.3 第3步:开发技术、集成技术与二次开发技术
的选型
9.6.4 第4步:评审3个备选架构,敲定概念架构方
案
第10章 细化架构设计
10.1 从2视图方法到5视图方法
10.1.1 回顾:2视图方法
10.1.2 进阶:5视图方法
10.2 程序员向架构师转型的关键突破——学会系统思考
10.2.1 系统思考之“从需求到设计”
10.2.2 系统思考之“5个设计视图”
10.3 5视图方法实践——5个视图、15个设计任务
10.3.1 逻辑架构=模块划分+接口定义+领域模型
10.3.2 开发架构=技术选型+文件划分+编译关系
10.3.3 物理架构=硬件分布+软件部署+方案优化
10.3.4 运行架构=技术选型+控制流划分+同步关系
10.3.5 数据架构=技术选型+存储格式+数据分布10.4 实际应用(8)——PM Suite贯穿案例之细化架构
设计
10.4.1 PM Suite接下来的设计任务
10.4.2 客户端设计的相关说明
10.4.3 细化领域模型时应注意的两点
第11章 架构验证
11.1 原型技术
11.1.1 水平原型vs.垂直原型,抛弃原型vs.演进原
型
11.1.2 水平抛弃原型
11.1.3 水平演进原型
11.1.4 垂直抛弃原型
11.1.5 垂直演进原型
11.2 架构验证
11.2.1 原型法
11.2.2 框架法
11.2.3 测试运行期质量,评审开发期质量
第3部分 模块划分专题
第12章 粗粒度“功能模块”划分
12.1 功能树
12.1.1 什么是功能树
12.1.2 功能分解≠结构分解
12.2 借助功能树,划分粗粒度“功能模块”
12.2.1 核心原理:从“功能组”到“功能模块”
12.2.2 第1步:获得功能树
12.2.3 第2步:评审功能树
12.2.4 第3步:粗粒度“功能模块”划分12.3 实际应用(9)——对比MailProxy案例的4种模块
划分设计
12.3.1 设计
12.3.2 设计的优点、缺点
12.4 实际应用(10)——做总体,要提交啥样的“子系
统划分方案”
第13章 如何分层
13.1 分层架构
13.1.1 常见模式:展现层、业务层、数据层
13.1.2 案例一则
13.1.3 常见模式:UI层、SI层、PD层、DM层
13.1.4 案例一则
13.2 分层架构实践技巧
13.2.1 设计思想:分层架构的“封装外部交互”思
想
13.2.2 实践技巧:设计分层架构,从上下文图开始
13.3 实际应用(11)——对比MailProxy案例的4种模块
划分设计
13.3.1 设计
13.3.2 设计的优点、缺点
第14章 用例驱动的模块划分过程
14.1 描述需求的序列图vs.描述设计的序列图
14.1.1 描述“内外对话”vs.描述“内部协作”
14.1.2 《用例规约》这样描述“内外对话”
14.2 用例驱动的模块划分过程
14.2.1 核心原理:从用例到类,再到模块
14.2.2 第1步:实现用例需要哪些类
14.2.3 第2步:这些类应该划归哪些模块14.3 实际应用(12)——对比MailProxy案例的4种模块
划分设计
14.3.1 设计
14.3.2 设计的优点、缺点
第15章 模块划分的4步骤方法——运用层、模块、功能模
块、用例驱动
15.1 像专家一样思考
15.1.1 自顶向下vs.自底向上,垂直切分vs.水平切
分
15.1.2 横切竖割,并不矛盾
15.2 模块划分的4步骤方法——EDD方法
15.2.1 封装驱动设计的4个步骤
15.2.2 细粒度模块的划分技巧
15.3 实际应用(13)——对比MailProxy案例的4种模块
划分设计
15.3.1 设计
15.3.2 设计的优点、缺点第1章 从程序员到架构师
自由竞争越来越健全,真正拥有实力的人越来越受到推崇。……
努力钻研,力求在更高水平上解决问题的专家不断增加,这正如电脑
处理信息的能力在不断提高一般。如今,这样的时代正在到来。
——大前研一,《专业主义》
机会牵引人才,人才牵引技术,技术牵引产品,产品牵引更大的
机会。在这四种牵动力中,人才所掌握的知识处于最核心的地位。
——张利华,《华为研发》
人才,以及合理的人才结构,是软件公司乃至软件业发展的关
键。
成才,并在企业中承担重要职责,是个人职业发展的关键。
1.1 软件业人才结构
1.1.1 金字塔型,还是橄榄型?
有人说,软件业当前的人才结构是橄榄型(中间大两头小),需
求量最大的“软件蓝领”短缺问题最为凸显,这极大地制约着软件业
的发展,因此要花大力气培养大量的初级软件程序员等“蓝领工
人”。
但业内更多人认为,软件业当前的人才结构是金字塔型,高手和
专家型人才的总量不足才是“制约发展”的要害,因此一方面软件工
程师应争取提升技能、升级转型,另一方面企业和产业应加强高级技
能培训、高级人才培养。
软件业的人才结构,到底是金字塔型,还是橄榄型?
本书认为,一旦区分开“学历结构”和“能力结构”,问题就不
言自明了(如图1-1所示):
· 学历结构=橄榄型。“中级学历”最多。有资料称,软件从业
者中研究生、本科与专科的比例大致是1:7:2。· 能力结构=金字塔型。“初级人才”最多。工作 3 年以上的软
件工程师,就一跃成为“有经验的中级人才”了吗?显然不一定。
· 有学历 ≠ 有能力。每个开发者真正追求的是,成为软件业
“人才能力结构”的顶级人才或中级人才。
图1-1 人才结构的两个视角
1.1.2 从程序员向架构师转型
人才能力的金字塔结构,注定了软件产业的竞争从根本上是人才
的竞争。具体到软件企业而言,一个软企发展的好坏,极大地取决于
如下人才因素:
· 员工素质。
· 人才结构。
· 员工职业技能的纵深积累。
· 员工职业技能的适时更新。
借用《华为研发》一书中的说法,“机会、人才、技术和产品是
公司成长的主要牵动力。机会牵引人才,人才牵引技术,技术牵引产
品,产品牵引更大的机会。在这四种牵动力中,人才所掌握的知识处
于最核心的地位。”然而,纯粹靠从外部“招人”,不现实。何况,软件企业、软企
的竞争对手和软件产业环境,都处在动态发展之中。因此,软件企业
应该:
· 定期分析和掌握本公司的员工能力状况、人才结构状况;
· 员工专项技能的渐进提升(例如架构技能、设计重构技能);
· 研发骨干整体技能的跨越转型(例如高级工程师向架构师、系
统工程师和技术经理的转型)。
对于本书的主题“软件架构设计能力的提升”而言,架构设计能
力是实践性很强的一系列技能,从事过几年开发工作是掌握架构设计
各项技能的必要基础。因此可以说,“从程序员向架构师转型”不仅
是软件开发者个人发展的道路之一,也是企业获得设计人才的合适途
径。
1.2 本书价值
本书包含3部分,分别是:
· 第1部分:基础概念篇。
· 第2部分:实践过程篇。
· 第3部分:模块划分专题。
读者可以根据自身发展状况、实际工作需要,选择合适的阅读路
径(如图1-2所示)。图1-2 不同目的,不同阅读路径
1.2.1 阅读路径1:架构设计入门
对于架构还未入门的程序员,推荐先重点阅读“基础概念篇”和
“模块划分专题”:
· 基础概念篇解析架构概念(第 2 章)之后,讲解如何运用
“逻辑视图+物理视图”设计架构(第3章)。
· 模块划分专题讲解模块划分的不同方法,将讨论功能模块、分
层架构、用例驱动的模块划分过程等内容(第12~15章)。
架构设计入门必过“架构视图关”。本书细致讲解“逻辑视图+物
理视图”的运用,如图 1-3所示,体会了“分而治之”和“迭代式设
计”这两点关键思想,运用“逻辑视图+物理视图”设计一个系统的架
构也就不那么难了。
图1-3 两视图法的“分而治之”和“迭代”思想
架构设计入门必过“模块划分关”。本书“模块划分专题”总结
了模块划分的 4 种方式,如图 1-4 所示。这其中,既有“水平分
层”、“垂直划分功能模块”和“从用例到类、再到模块”等设计思
想,也有不推荐的想到哪“切”到哪的设计方式。图1-4 业界模块划分的4种做法
当一个程序员,看懂了他们团队的架构师是如何划分模块的(甚
至问“你为啥只垂直切子系统没分层呢”),那他离成为架构师还远
吗?
1.2.2 阅读路径2:领会大系统架构设计
入门之后,进一步学习大型系统架构成败的关键——概念架构设
计。推荐精读如下两章:
· 第8章。如何确定影响架构设计的关键需求。
· 第9章。概念架构如何设计。
小系统和大系统的架构设计之不同,首先是“概念架构”上的不
同,而归根溯源这是由于架构所支撑的“关键需求”不同造成的。整
个架构设计过程中的“确定关键需求”这一环节,可谓小系统和大系
统架构设计的“分水岭”,架构设计走向从此大不相同。
概念架构是直指系统目标的设计思想、重大选择,因而非常重
要。《方案建议书》《技术白皮书》和市场彩页中,都有它的身影,以说明产品项目方案的技术优势。因此,也有人称它为“市场架
构”。
概念架构设计什么?从设计任务上,概念架构要明确“1 个决
定、4个选型”,如图1-5所示。
图1-5 概念架构设计什么?
概念架构如何设计?从设计步骤的顺序上,本书推荐(如图1-6所
示):
· 首先,选择架构风格、划分顶级子系统。这两项设计任务是相
互影响、相辅相成的。
· 然后,开发技术选型、集成技术选型、二次开发技术选型。这
三项设计任务紧密相关、同时进行。另外可能不需要集成支持,也可
以决定不支持二次开发。图1-6 概念架构如何设计?
1.2.3 阅读路径3:从需求到架构的全过程
专业的架构设计师,必须掌握架构设计的“工程化过程”。以此
为目标的读者,请精读“实践过程篇”的内容。
· 第 4 章。概述从需求到架构的全过程,还提供了一节叫“速
查手册”,供快速查阅每个环节的工作内容。
· 第5~11章。按如下6 个环节的展开讨论:需求分析、领域建
模、确定关键需求、概念架构设计、细化架构设计、架构验证。
内容虽多,用一幅图概括也不是不可能,在为企业培训架构时我
们就经常这么做——图 1-7即,展示了从需求到架构整个过程中的关
键任务项。图1-7 架构设计的全过程
1.2.4 阅读路径4:结合工作,解决实际问题
最后,按照经典名著《如何阅读一本书》中所说的“主动阅读”
法,读者还可以“带着问题”、“以我为主”地“跳读”。
【实际问题1】 开发人员的一个很经典的困惑是:领域经验不足
怎么办?
本书第7章,给出了建议。破解“领域知识不足”死结的一个有效
方法,是把领域模型作为“理解领域的手段”。领域模型的“强项”
是“理顺概念关系、搞清业务规则”——通过对复杂的领域进行“概
念抽象”和“关系抽象”建立模型、获得对领域知识总体上的把握,就不会掉入杂乱无章的概念“堆”里了。
【实际问题 2】 又例如,你所在的部门,是否存在这样的问
题:不同的人对架构有不同的理解?
本书第2章,推荐结合部门的实际工作,来理解架构的含义,统一
团队不同成员对架构的理解。【实际问题3】 用例建模够不够?流程建模要不要?笔者接触的
很多实践者,都有此困惑。
本书第6章,简述了需求分析“三套实践论”的观点,提出“大、中、小”三套可根据系统特点选择的需求实践策略,可供实践者参
考。如图1-8、图1-9和图1-10所示。
图1-8 需求实践论之小型方法
图1-9 需求分析实践论之中型方法图1-10 需求实践论之大型方法
由此可见,是实践决定方法,不是方法一刀切实践。
更多问题的解决思路在此不再列举,祝阅读之旅愉快!第1部分 基本概念篇
第2章 解析软件架构概念
什么是架构?如果你问五个不同的人,可能会得到五种不同的答
案。
——lvar Jacobson,《AOSD中文版》
很多人都试图给“架构”下定义,而这些定义本身却很难统一。
——Martin Fowler,《企业应用架构模式》
不积跬步,无以至千里。
程序员在向架构师转型时,都希望尽早弄清楚“什么是架构”。
但是,架构的定义又多又乱,已造成“什么是架构”成了程序员向架
构师转型的“大门槛”。
本章,我们讨论软件架构的概念。
值得说明的是,人们对“Architecture”有着不同的中文叫法,比如架构、构架和体系结构等。本书将一贯地采用“架构”的叫法;
当然,当引用原文或提及书名时将保留原来的叫法。
2.1 软件架构概念的分类
一个词(比如“电脑”),可能并不代表一件单独的东西,而是
代表了一类事物。这个一般性的表述就是我们通常所说的“概念”。
也许读者期待一个干净利落的软件架构概念,但这有点儿难。对
此,Martin Fowler给出的评价是:
软件业的人乐于做这样的事——找一些词汇,并将它们引申到大
量微妙而又相互矛盾的含义中。一个最大的受害者就是“架构”这个
词。……很多人都试图给“架构”下定义,而这些定义本身却很难统
一。
本书将软件架构概念分为两大流派——组成派和决策派,帮助各
级开发人员快速理清“什么是架构”的基础问题。下面就采用这种方式介绍架构概念。
2.1.1 组成派
Mary Shaw 在《软件体系结构:一门初露端倪学科的展望》中,为“软件架构”给出了非常简明的定义:
软件系统的架构将系统描述为计算组件及组件之间的交互。(The
arc hitecture of a software system defines that system in
terms of computational components and interactions among
those components.)
必须说明,上述定义中的“组件”是广泛意义上的元素之意,并
不是指和 CORBA、DCOM、EJB 等相关的专有的组件概念。“计算组
件”也是泛指,其实计算组件可以进一步细分为处理组件、数据组
件 、 连 接 组 件 等 。 总 之 , “ 组 件 ” 可 以 指 子 系 统 、 框 架
(Framework)、模块、类等不同粒度的软件单元,它们可以担负不同
的计算职责。
上述定义是“组成派”软件架构概念的典型代表,有如下两个显
著特点:
(1)关注架构实践中的客体——软件,以软件本身为描述对象;
(2)分析了软件的组成,即软件由承担不同计算任务的组件组
成,这些组件通过相互交互完成更高层次的计算。
2.1.2 决策派
RUP(Rational Unified Process,Rational统一过程)给出的架
构的定义非常冗长,但其核心思想非常明确:软件架构是在一些重要
方面所做出的决策的集合。下面看看它的定义:
软件架构包含了关于以下问题的重要决策:
· 软件系统的组织;
· 选择组成系统的结构元素和它们之间的接口,以及当这些元素
相互协作时所体现的行为;
· 如何组合这些元素,使它们逐渐合成为更大的子系统;· 用于指导这个系统组织的架构风格:这些元素以及它们的接
口、协作和组合。
· 软件架构并不仅仅注重软件本身的结构和行为,还注重其他特
性:使用、功能性、性能、弹性、重用、可理解性、经济和技术的限
制及权衡,以及美学等。
该定义是“决策派”软件架构概念的典型代表,有如下两个显著
特点:
(1)关注架构实践中的主体——人,以人的决策为描述对象;
(2)归纳了架构决策的类型,指出架构决策不仅包括关于软件系
统的组织、元素、子系统和架构风格等几类决策,还包括关于众多非
功能需求的决策。
2.1.3 软件架构概念大观
下面再列举几个著名的软件架构定义,请大家:
· 结合实践,体会自己所认为的“架构”是什么,也可问问周围
同事对架构的理解;
· 体会专家们给“架构”下的定义虽多,但万变不离其宗——都
是围绕“组成”和“决策”两个角度定义架构的;
· 注意区分,下面的定义1和定义2属于架构概念的“决策派”,而定义3、4、5、6、7属于架构概念的“组成派”;
· 关注定义 7(来自 SEI 的 Len B ass 等人),它将架构的多
视图“本性”体现到了定义当中,是相对比较新的定义,业界都深表
认同。
1.Booch、Rumbaugh和Jacobson的定义
架构是一系列重要决策的集合,这些决策与以下内容有关:软件
的组织,构成系统的结构元素及其接口的选择,这些元素在相互协作
中明确表现出的行为,这些结构元素和行为元素进一步组合所构成的
更大规模的子系统,以及指导这一组织——包括这些元素及其接口、它们的协作和它们的组合——架构风格。
2.Woods的观点Eoin W oods 是这样认为的:软件架构是一系列设计决策,如果
做了不正确的决策,你的项目可能最终会被取消(Software
architecture is the set of de sign deci sions which,if made
incorrectly,may cause your project to be cancelled.)。
3.Garlan和Shaw的定义
Garlan 和 Shaw 认为:架构包括组件(Component)、连接件
(Connector)和约束(Constrain)三大要素。组件可以是一组代码
(例如程序模块),也可以是独立的程序(例如数据库服务器)。连
接件可以是过程调用、管道和消息等,用于表示组件之间的相互关
系。“约束”一般为组件连接时的条件。
4.Perry和Wolf的定义
Perry和Wolf提出:软件架构是一组具有特定形式的架构元素,这
些元素分为三类:负责完成数据加工的处理元素(Processing Ele
ments)、作为被加工信息的数据元素(Data Elem ents)及用于把架
构的不同部分组合在一起的连接元素(Connecting Elements)。
5.Boehm的定义
Barry Boeh m 和他的学生提出:软件架构包括系统组件、连接件
和约束的集合,反映不同涉众需求的集合,以及原理(Rationale)的
集合。其中的原理,用于说明由组件、连接件和约束所定义的系统在
实现时,是如何满足不同涉众需求的。
6.lEEE的定义
IEEE 610.12-1 990 软件工程标准词汇中是这样定义架构的:架
构是以组件、组件之间的关系、组件与环境之间的关系为内容的某一
系统的基本组织结构,以及指导上述内容设计与演化的原理
(Principle)。
7.Bass的定义
SEI(Software Engineering Institute,SEI,美国卡内基·梅
隆大学软件研究所)的 Len B ass等人给架构的定义是:某个软件或
计算机系统的软件架构是该系统的一个或多个结构,每个结构均由软
件元素、这些元素的外部可见属性、这些元素之间的关系组成。(The
softwa re architecture of a program or co mputing sy stem isthe struct ure or structures of the sy stem,which co mprise
softwar e elements , the externally visible properties of
those elements,and the relationships among them.)
2.2 概念思想的解析
2.2.1 软件架构关注分割与交互
架构设计是分与合的艺术。
“软件系统的架构将系统描述为计算组件及组件之间的交互”,Shaw 的这个定义从“软件组成”角度解析了软件架构的要素:组件及
组件之间的交互。如图2-1所示(采用UML类图),架构=组件+交互,组件和组件之间有交互关系(图中的“交互”关系建模成UML关联
类)。
下面以大家熟悉的MVC架构为例进行说明。如图2-2所示。
· 采用MVC架构的软件包含了这样3种组件:Model、View、Controller。
· 这 3 种组件通过交互来协作:View 创建 Controller 后,Controller 根据用户交互调用Model的相应服务,而Model会将自身的
改变通知View,View则会读取Model的信息以更新自身。
图2-1 软件架构的要素:组件及组件之间的交互图2-2 MVC架构作为“组件+交互”的例子
通过此例可以看出,“组件+交互”可以将 MVC 等“具体架构设
计决策”高屋建瓴地抽象地表达出来。
2.2.2 软件架构是一系列有层次的决策
架构属于设计,但并非所有设计都属于架构。架构涉及的决策,往往对整体质量、并行开发、适应变化等方面有着重大影响(否则就
放到详细设计环节了):
· 模块如何划分。
· 每个模块的职责为何。
· 每个模块的接口如何定义。
· 模块间采用何种交互机制。
· 开发技术如何选型。
· 如何满足约束和质量属性的需求。
· 如何适应可能发生的变化。……
还有很多
而且实际的设计往往是分层次依次展开的——无论是决策如何切
分系统还是决策技术选型都是如此:
· 例如,你设计一个 CS 系统时,是不是经历着这样一个“决
策树”过程:……嗯,我决定采用 CS 架构,系统包含 Client 和Server;……嗯,我决定将 Server 分为三层;……嗯,我决定将
Server的引擎层划分为N个模块;……(如图2-3所示。)
· 例如,你设计一个 BS 系统时,可曾有过这样的“决策过
程”:……嗯,我决定 BS前端采用JSP技术;……嗯,具体到
Framework我选Struts;……(如图2-4所示。)再举一例。现在你来
设计一个硬件设备调试系统。
图2-3 架构设计过程是一棵决策树(切分类决策)
图2-4 架构设计过程是一棵决策树(技术选型类决策)第1步,理解需求——此时软件系统是黑盒子
如图2-5所示,你要设计的系统现在还未切分,它的主要需求目标
有:
· 作为设备调试系统,其主要功能是实时显示设备状态,以及支
持用户发送调试命令;
· 另外,由于是为硬件产品配套的软件系统,所以它必须容易被
测试,否则是硬件故障还是软件故障将很难区分;
· 再就是必须具有很高的性能,具体性能指标为“每秒钟能够刷
新 5 次设备状态的显示,并同时支持一个完整命令字的发送”。
第2步,首轮决策——此时软件系统被高层切分
之后,软件架构师必须规划整个系统的具体组成。通常,对于一
个独立的软件系统而言,它常常被划分为不同的子系统或分系统,每
个部分承担相对独立的功能,各部分之间通过特定的交互机制进行协
作。
图2-5 设备调试系统:主要目标(CRC卡)
而此例中的设备调试系统则不同,它有两个相对独立的应用组
成:一个桌面应用和一个嵌入式应用。
那么,它们如何通信呢?最终决定,将它们通过串口连接,采用
RS232协议进行通信。
再接下来,架构师必须决定这两个应用分别担负哪些职责(如图
2-6 中的 CRC 卡所示):桌面应用部分负责提供模拟控制台和状态显示;而嵌入式应用部分负责设备的控制和状态数据的读取。
图2-6 设备调试系统:组成部分(CRC卡)
第3~N步,继续决策——此时软件系统被切分成更小单元……现在,设备调试系统的桌面应用部分,也要划分成模块吧
(如图2-7所示)。
通信部分被分离出来作为通信层,它负责在 RS232 协议之上实现
一套专用的“应用协议”:当应用层发送来包含调试指令的协议包
时,它会按 RS232 协议将之传递给嵌入部分;当嵌入部分发送来原始
数据时,它将之解释成应用协议包发送给应用层。
而应用层负责设备状态的显示,提供模拟控制台供用户发送调试
命令,并使用通信层和嵌入部分进行交互。……如此步步设计下去,你就该问自己“架构的哪些目标还未达
成”诸如此类的问题了。例如“应用层”怎样高速响应用户?例如
“通信层”如何高性能地接受串口数据而不造成数据丢失?在此不再
赘述。图2-7 其中的桌面应用:进一步分解(CRC卡)
2.2.3 系统、子系统、框架都可以有架构
虽然我们最常听到的说法是“软件系统的架构”,但未必是完整
的软件系统才有架构。真实的软件其实是“由组件递归组合而成”
的,图2-8运用Composite模式刻画了这一点:
· 组件的粒度可以很小,也可以很大;任何粒度的组件都可以组
合成粒度更大的整体。即所谓的粒度多样性问题;
· 组件粒度的界定,必须在具体的实践上下文中才有意义;你的
大粒度组件,对我而言可能是原子组件。即所谓的粒度相对性问题;
· 组件分为原子组件和复合组件两种;在特定的实践上下文中,原子组件是不可再分的;复合组件是由其他组件(既可以是原子组
件,又可以是复合组件)组合而成的;无论是原子组件还是复合组
件,它们之间都可以通过交互来完成更复杂的功能。图2-8 借助Composite模式刻画真实的软件
是时候为“软件架构”找准位置了,答案看上去惊人的简单(如
图2-9所示):
· 架构设计是针对作为复合整体的“复杂软件单元”的,架构规
定了“复杂软件单元”如何被设计的重要决策;
· 实际上,系统、子系统和框架(Framework)根据需要都可以
进行架构设计。图2-9 为“软件架构”找准位置
例如,航空航天领域的系统往往极为复杂,这样一来,总的系统
需要配备系统架构师,子系统有时也会分别单独配备架构师。
又例如,用友华表 Cell 组件是标准的报表处理 ActiveX 组件,它提供几百个编程接口。虽然在用户看来它只是小小的“开盒即用”
的ActiveX 组件(上面说的“原子组件”),但它的研发团队从需求
分析到架构设计到程序开发……都样样经历(上面说的“复杂软件单
元”)。
再例如,随着面向服务架构(Service Oriented Architecture,SOA)被越来越多的人所接受,基于组件的软件工程(Component
Based Software Engineering,CBSE)也为更多的人所认识。在此种
情况下,整个系统的架构模式是 SOA,而每个组件本身也有自己的架
构设计——在实践中不了解这一点会很危险。
推广开去,其实任何作为复合整体的复杂事物都可能有架构,比
如一本书、一幢建筑物。那本“永不褪色的经典”《如何阅读一本书》中就说:“每一本书的封面之下都有一套自己的骨架(Every
book has a skeleton hidden between its boards)。”
2.3 实际应用(1)——团队对架构看法不一怎么办
2.3.1 结合手上的实际工作来理解架构的含义
你们公司,你所在的部门,是否存在这样的问题:不同的人对架
构有不同的理解?
看法影响做法。先说程序员。如果程序员们对他们公司架构师的
做法“不以为然”,会不会不按照架构进行后续的详细设计和编程
呢?……这让我们不禁想到,程序代码实际体现的设计和《架构设计
文档》差别很大,是很多公司都存在的现象。这背后,难道没有“程
序员和架构师对架构有不同的理解”这一原因吗!
再说架构师。如果一个架构师认为“架构就是通用模块”,那么
他可能就不会关心非通用单元的设计。如果一个架构师认为“架构就
是技术选型”,那么他在拍板儿选择“Spring+S truts”之后就理所
当然地无事可做了。如果一个架构师认为“投标时讲的架构就是架构
的全部”,那么他才不管那“三页幻灯”对程序员的实际开发指导不
够呢(因为没有意识到)。
怎么办呢?
一通理论说教是不行的。太空洞,到了实际工作中,理解依然、做法照旧。
结合手上的实际工作来理解架构的含义,是笔者推荐的做法。
2.3.2 这样理解“架构”对吗
某公司,研发二部,他们一直在做的软件产品叫PM Suite,是一
套项目管理系统。
老王,研发二部部长,经验丰富、设计功力也非常深厚。
小张,众多程序员的代表,开发骨干,功底扎实、头脑灵活、工
作努力。小张希望能在 1~2年之内,从程序员转型成为架构师。关于“什么是架构”,小张是这么理解的:
在一些大型项目或者大型公司里,都是由架构师编写出系统接
口,具体的实现类交给了程序员编写,公司越大这种情况越明显,所
以在这些公司里做开发,我们可能都不知道编写出的系统是个什么样
子,每天做的工作可能就是做“填空题”了。
当你发现越来越灵活地使用接口时,那么你就从程序员升级为架
构师了。
老王用3个公式概括了一下小张的理解:
程序=类+类级接口
架构设计=定义类级接口
编程开发=像做填空题似的写实现类
这可行吗?将架构设计一下子细致到类:一是难度太大不现实,二是工作量太大没必要,三是并发呀部署呀都没考虑、性能安全可伸
缩等需求能达标?……于是老王开始担心了。
2.3.3 工作中找答案:先看部分设计
老王找来小张,铺开纸笔,开始拿实际工作来“说事儿”。他
说:
咱们的 PM Su ite 系统,有一项名为“查看甘特图”的需求,用
户要求“能够以甘特图方式查看任务的起始时间、结束时间、任务承
担者等信息”。经过分析我们不难发现,PM Suite 至少应提供两种查
看任务计划的方式:一种是以表格的方式将任务名称、开始时间等信
息列出,另一种是采用甘特图。如图2-10所示。图2-10 PM Suite至少要提供两种查看任务计划的方式
任务是如何计划的?又具体分配给哪些项目成员?这些信息和 PM
Su ite 采用何种方式来展现应当是没有关系的。根据此分析,我们立
即想到采用 MVC 架构,将业务逻辑和展现逻辑分开,如图2-11所示。
图2-11 和具体技术无关的架构方案上面的架构设计,还处于“和具体技术无关”的层面。我们必须
考虑更多的实际开发中要涉及的技术问题,从而不断细化架构方案,这样才能为开发人员提供更多的指导和限制,也才能真正降低后续开
发中的重大技术风险。
对于 PM Suite 要显示甘特图而言,“甘特图绘制包”是自行开
发的,还是采用的第三方SDK,就是一个很重要的技术问题。考虑如
下:
· 一方面,用户根本不关心“甘特图绘制包”的问题,他们只在
乎自己的需求是否得到了满足;而项目工期是很紧的,自行开发“甘
特图绘制包”势必增加其他工作的压力,为什么不采用第三方SDK呢?
· 另一方面,短期内决定采用的第三方“甘特图绘制包”可能并
不是最优的,所以并不希望PM Suite“绑死”在特定“甘特图绘制
包”上。
基于以上分析,架构师会决定:采用第三方 SDK,但会自主定义
“甘特图绘制接口”将SDK隔离。如图2-12所示。图2-12 和技术相关的架构方案
有的读者应该已经看出来了,上述设计中采用了Adapter设计模
式。
适配器(Adapter)模式
关键字:已存在不可预见 复用
支持变化:由于 Adapter 提供了一层“间接”,使得我们可以复
用一个接口不符合我们需求的已存在的类,也可以使一个类
(Adaptee)在发生不可预见的变化时,仅仅影响 Adapter而不影响
Adapter的客户类。
结构:
2.3.4 工作中找答案:反观架构概念的体现
看到小张听得挺有感觉,老王话锋一转,话题落于架构的理解
上。他说:
有关PM Suit e的设计,先讲到这儿,我再简单说一下“什么叫架
构”。架构的定义很乱,但可以分为两派。
组成派:架构=组件+交互
决策派:架构=一组重要决策刚才有关 PM Suite 的设计虽然仅涉及架构的“冰山一角”,但
仍然可以体现软件架构的概念——对组成派和决策派的架构概念都有
体现。
先说组成派的架构概念,它强调软件架构包含了“计算组件及组
件之间的交互”。组件体现在哪里呢?
· 【回顾图 2-11】 。“业务层”和“展现层”就是两个组
件;当然,这两个组件粒度很粗,并且完全是黑盒。
· 【到了图 2-12】 。为了支持 MVC 协作机制,设计中引入了
PrgMgtModel、GanttChart和 GanttChartImpl 等关键类。可以说,“业务层”和“展现层”两个组件在某种程度上已从黑盒变成了灰
盒,从而能提供更具体的开发指导。
那么,软件架构概念中所说的“交互”体现在哪里呢?
· 【回顾图 2-11】 。“业务层”和“展现层”两个粗粒度组
件之间的交互为:展现层从业务层“读取数据”。
· 【到了图 2-12】 。“读取数据”这一交互已经“具体落
实”成了“GanttChartImpl 从PrgMgtModel读取数据”。另外,图中
还有两个“调用”关系。
由此看来,组成派软件架构概念完全是对架构设计方案的忠实概
括,只不过有一点儿抽象罢了。
再看看决策派的架构概念,它归纳了架构决策的类型,指出架构
决策不仅包括关于软件系统的组织、元素、子系统、架构风格等的几
类决策,还包括关于众多非功能需求的决策。
· 【回顾图 2-11】 。业务层和展现层分离,体现了架构概念
中的“软件系统的组织”决策,业界也普遍认同。
· 【到了图2-12】 。为了防止PM Suite“绑死”在特定甘特图
绘制包上,设计中引入自主定义的GanttChart接口,让实现该接口的
GanttChartImpl转而调用第三方SDK(其实就是 Adapter 设计模
式)。这样一来,架构就有了弹性——当发现功能更强大的甘特图程
序包时(或决定直接调用Java 2D自行开发甘特图绘制部分时),可以
方便地仅更改GanttChartImpl,而其他组件不用更改(如图2-13所
示)。图2-13 软件架构如何具有弹性
老王最后说:呵呵,组成派和决策派无非是个叫法,它们只不过
是所站的角度不同罢了,你在具体设计一个架构时都会有所体现的。第3章 理解架构设计视图
“有角度就有空间”。……多视图方法背后的核心思想有些相
似:从不同角度,规划“分割”与“交互”。
——温昱,《一线架构师实践指南》
不同的视图支持不同的目标和用途。
——Paul Clements,《软件构架编档》
架构设计是一门解决复杂问题的艺术。
设计任何复杂系统时,架构视图都是不可或缺的(无一例外)。
但由于在日常开发工作中较少接触,大部分程序员对“设计视图”的
思想还比较陌生。
本章围绕“架构视图”这一主题,将逐次讨论:
· 设计架构时,架构视图为什么必不可少?【本章问题1】
· 什么是架构视图?【本章问题2】
· 如何运用“逻辑视图+物理视图”设计一个系统的架构?【本
章问题3】
3.1 软件架构为谁而设计
办公室里,关于什么是软件架构,争论正酣。
程序员说 ,软件架构就是要决定需要编写哪些 C 程序或 OO
类、使用哪些现成的程序库(Library)和框架(Framework)。程序
经理笑了 。
程序经理说 ,软件架构就是模块的划分和接口的定义。系统分
析员笑了 。
系统分析员说 ,软件架构就是为业务领域对象的关系建模。配
置管理员笑了 。
配置管理员说 ,软件架构就是开发出来的以及编译过后的软件到
底是个啥结构。数据库工程师笑了 。数据库工程师说 ,软件架构规定了持久化数据的结构,其他一切
只不过是对数据的操作而已。部署工程师笑了 。
部署工程师说 ,软件架构规定了软件部署到硬件的策略。用户
笑了 。
用户说 ,软件架构应该将系统划分为一个个功能子系统。程序员
又笑了 。
大家想了想说 ,我们都没错呀,所有这些方面都是需要的啊。……软件架构师哭了 。
由此看来,不同涉众看待架构的视角是不同的,而架构师要为不
同的涉众而设计。
怎么办呢?同时关注多个架构设计视图。架构视图的本质是“分
而治之”,能帮助架构师从不同角度设计,特别是面对复杂系统时
“分而治之”地设计是必需的。
这就回答了“设计架构时,架构视图为什么必不可少”的问题
【本章问题1】 。
3.1.1 为用户而设计
为什么要开发某个软件系统呢?因为要给用户使用:或辅助用户
完成日常工作,或帮助用户管理某些信息,或给用户带来娱乐体
验……不一而足。
用户要功能,用户也要质量。
每套软件都会提供这样或那样的功能,正是这些功能帮助用户实
现他们在工作或生活中的特定目标。用户所需的功能和系统本身的结
构一定是相互影响的,这正是软件架构师要特别关注的。先举个生活
中的例子吧。例如,因为功能不尽相同,所以“转笔刀”的结构和
“专用刀片”的结构也不一样(如图 3-1 所示):小学生需要削铅
笔,那一定是转笔刀最适合他们,因为方便易用,一转即可;而美术
师需要用铅笔来画素描,他们则需要使用专用刀片,因为转笔刀难以
削出满足不同绘画要求的形状各异的笔尖。同样,对于软件系统而
言,用户需求是千差万别的,我们采用的软件架构必须和所要提供的
功能相适应。因此,软件架构师必须时时牢记:为用户而设计。图3-1 生活中的例子:功能与结构相互影响
诸如性能、易用性等软件质量属性,并不像上面所述的软件功能
那样直接帮助用户达到特定目标,但并不意味着软件质量属性不是必
需的——恰恰相反,质量属性差的软件系统大多都不会成功。例如,你提供了用户要求的“交易查询”功能,但这一功能动辄就需要花上
几分钟,用户能接受吗?当然不能接受。用户会说,功能虽然具备
了,但质量太差难以接受。用户在使用软件系统的过程中,其关心的
质量属性可能包括易用性、性能、可伸缩性、持续可用性和鲁棒性
等。因此,软件架构师也应当时时牢记:为用户而设计,不仅满足用
户要求的功能,也要达到用户期望的质量。
3.1.2 为客户而设计
很多时候,客户(Customer) ≠ 最终用户(User)。
例如,对超市销售系统而言,客户是某家连锁超市(的老板),而用户则是超市收银员和上货员。
架构师为客户而设计:充分考虑客户的业务目标、上线时间的要
求、预算限制,以及集成需要等,还要特别关注客户所在领域的业务
规则和业务限制。为此,架构师应当直接或(通过系统分析员)间接
地了解和掌握上述需求及约束,并深刻理解它们对架构的影响,只有
这样才能设计出合适的软件架构。合适的才是最好的,例如,如果客
户是一家小型超市,软件和硬件采购的预算都很有限,那么你就不宜
采用依赖太多昂贵中间件的软件架构设计方案。
3.1.3 为开发人员而设计先研究需求,再设计架构,然后交由开发人员编程……作为架
构,不仅要为“上游”的需求而设计,还要为“下游”的开发人员而
设计。
例如,性能是软件运行期质量属性,最关心性能的人其实是客
户;但可扩展性是软件开发期质量属性,项目开发人员和负责升级维
护的开发人员最关心。
推及开去,其实,并不是所有需求都来自用户,软件的可扩展
性、可重用性、可移植性、易理解性和易测试性等非功能需求更多地
考虑对开发人员的影响。这类“软件开发期质量属性”深刻影响开发
人员的工作,使开发更顺畅抑或更艰难。
3.1.4 为管理人员而设计
软件变得越来越复杂,单兵作战不再普遍,取而代之的是团队开
发。而团队开发又反过来使软件开发更加复杂,因为现在不仅仅要面
临技术复杂性的问题了,还有管理复杂性的问题。
开发人员之间的依赖,源自他们负责的程序之间的依赖(如图 3-
2 所示)。要理清并管理人员协作,就应该搞清楚系统一级“模块+交
互”的设计,搞清楚架构。可见,架构是开发管理的核心基础。
图3-2 开发人员之间的依赖,源自他们负责的程序之间的依赖
看来,软件架构师也应为管理人员而设计。例如,对软件项目管理而言,软件架构应当起到应有的作用:为
项目经理制定项目计划、管理项目分工和考核项目进度等提供依据。
一方面,软件架构从大局着手,就技术方面的重大问题作出决策,构
造一个由粗粒度模块组成的解决方案,从而可以把不同模块分配给不
同小组分头开发。另一方面,软件架构设计方案规定了各模块之间如
何交互的机制和接口,在开发小组之间起到“沟通桥梁”和“合作契
约”的作用。
再例如,对软件配置管理而言,软件架构师亦应顾及。一般而
言,在软件架构确定之前,软件配置管理是无法全面开展的。配置管
理员应该能够从软件架构方案中了解到开发出来的软件以什么样的目
录结构存在,以及编译过后的软件目标模块放到哪个目录等决定,并
以此作为制定配置管理基本方案的基础。
3.1.5 总结
架构师应当为项目相关的不同角色而设计(如图 3-3 所示)——
只有这样,软件架构才能和它“包含了关于如何构建软件的一些最重
要的设计决策”的“地位”相符。
图3-3 软件架构为谁而设计· 架构师要为“上游”客户负责,满足他们的业务目标和约束条
件;
· 架构师要为“上游”用户负责,使他们关心的功能需求和运行
期质量属性得以满足;
· 架构师必须顾及处于协作分工“下游”的开发人员;
· 架构师还必须考虑“周边”的管理人员,为他们进行分工管
理、协调控制和评估监控等工作提供清晰的基础。
3.2 理解架构设计视图
什么是架构视图呢?【本章问题2】
3.2.1 架构视图
架构视图的实践导向性很强,每个视图分别关注不同的方面,针
对不同的实践目标和用途。Philippe Kruchten在其著作《Rational统
一过程引论》中写道:
一个架构视图是对于从某一视角或某一点上看到的系统所作的简
化描述,描述中涵盖了系统的某一特定方面,而省略了与此方面无关
的实体。
架构视图是一种设计架构、描述架构的核心手段:
· 也就是说,架构要涵盖的内容和决策太多了,超过了人脑“一
蹴而就”的能力范围,因此采用“分而治之”的办法从不同视角分别
设计;
· 同时,也为软件架构的理解、交流和归档提供了方便。
在多种架构视图中,最常用的是逻辑架构视图和物理架构视图
(本章稍后讨论如何运用“逻辑视图+物理视图”设计架构)。
3.2.2 一个直观的例子
在讲解软件的逻辑架构视图和物理架构视图之前,先看一个生活
中视图的例子。图 3-4 所示的世界人口分布图,是社会学家关心的;而气候学
家,则更关心图 3-5 所示的世界年降水量分布图。这其实就运用了
“视图”的手段,用不同视图来刻画我们关心的世界的不同方面——
你完全可以将“世界人口分布图”称为“世界的人口分布视图”。
当然,更进一步而言,同一事物的不同视图之间是有联系的。例
如,从图 3-4 和 3-5 上看,除了南美洲之外基本都是降水量足的地
方人口较密集。我们下面将讨论的软件架构视图也是这样,不同视图
之间存在相互影响。
图3-4 世界人口分布图(图片来源:www.dlpd.com)图3-5 世界年降水量分布图(图片来源:www.dlpd.com)
3.2.3 多组涉众,多个视图
首先,考虑软件架构的表达与交流。
这是个很现实的问题。究其原因,由于角色和分工不同,整个软
件团队以及客户等涉众各自需要掌握的技术或技能存在很大差异,为
了完成各自的工作,他们需要了解整套软件架构决策的不同子集。所
以,软件架构师应当提供不同的软件架构视图,以便交流和传递设计
思想。例如:
· 系统工程师:由于负责部署和运营维护,他们最关心软件系统
基于何种操作系统之上、依赖于哪些软件中间件、有没有群集或备份
等部署要求、驻留在不同机器上的软件部分之间的通信协议是什么等
决策;
· 而开发人员:则最关心软件架构方案中关于模块划分的决定、模块之间的接口如何定义、甚至架构指定的开发技术和现成框架是不
是最流行的等问题;……
不一而足。相反,如果不同视图混为一谈,《架构文档》理解起来会非常困
难、甚至看不懂。对此,Peter Herzum等人在Business Component
Factory一书中曾指出:
总的来说,“架构”一词涵盖了软件架构的所有方面,这些方面
紧紧地缠绕在一起,决定如何将之分割成部分和主题显得相当主观。
既然如此,就必须引入“架构视点”作为讨论、归档和理解大型系统
架构的手段。(Generally speaking,the term architecture can
be seen as covering all a spects of a soft ware architect
ure.All its aspects re deeply intertwined,an d it is really
a subj ective decisi on to split it up in parts and su
bjects.Having said that , the u sefulness of int roducing
archit ectural viewp oints is e ssential as a way of
discussing,documenting,and mastering the architecture of
large-scale systems.)
第二,考虑软件架构的设计。
这个问题更为关键。软件架构是个复杂的整体,架构师可以“一
下子”把它想清楚吗?当然不能。有关思维的科学研究表明,越是复
杂的问题越需要分而治之的思维方式:
· 将“架构视图”作为分而治之的手段,使架构师可以分别专注
于架构的不同方面,相对独立地分析和设计不同“子问题”,这相当
于将“整个问题”简化和清晰化了;
· 再也不必担心逻辑层(Layer)、物理层(Tier)、功能子系
统、模块、接口、进程、线程、消息和协议等设计统统混为一“潭”
(泥潭?)了。
不幸的是,大多数书籍中都强调多视图方法是软件架构归档的方
法,却忽视了该方法对架构设计思维的指导作用。而本书强调,多视
图不仅是归档方式,更是架构设计的思维方式。
3.3 运用“逻辑视图+物理视图”设计架构
无论是软件架构,还是现实生活,运用“逻辑视图+物理视图”刻
画大局,都方便有效。图 3-6 所示为办公室局域网:从物理角度看,所有计算机“毫无区别”地连接到路由器上;而从逻辑角度看呢,一
台计算机充当文件服务器,而其他计算机是可以访问服务器的客户
机。
图3-6 区分物理视角与逻辑视角
那么,如何运用“逻辑视图+物理视图”设计一个系统的架构呢?
【本章问题3】
3.3.1 逻辑架构
软件的逻辑架构规定了软件系统由哪些逻辑元素组成以及这些逻
辑元素之间的关系。具体而言,组成软件系统的逻辑元素可以是逻辑
层(Layer)、功能子系统、模块。
设计逻辑架构的核心任务,是比较全面地识别模块、规划接口,并基于此进一步明确模块之间的使用关系和使用机制。图3-7展示了一
个网络设备管理系统逻辑架构设计的一部分,“模块+接口”是其设计
的基本内容:
· 识别模块(例如,图中的TopoGraphModel等);
· 规划模块的接口(例如,图中的StatusChangedRender等);
· 明确模块之间的使用关系和使用机制(例如,图中的
StatusChanged 是由GeneralModel创建的消息,以参数的形式传递给StatusChangedRender接口)。
图3-7 软件逻辑架构设计的核心任务
3.3.2 物理架构软件的物理架构规定了组成软件系统的物理元素,这些物理元素
之间的关系,以及它们部署到硬件上的策略。
物理架构可以反映出软件系统动态运行时的组织情况。此时,上
述物理架构定义中所提及的“物理元素”就是进程、线程,以及作为
类的运行时实例的对象等,而进程调度、线程同步、进程或线程通信
等则进一步反映物理架构的动态行为。
随着分布式系统的流行,“物理层(Tier)”的概念大家早已耳
熟能详。物理层和分布有关,通过将一个整体的软件系统划分为不同
的物理层,可以把它部署到分布在不同位置的多台计算机上,从而为
远程访问和负载均衡等问题提供了手段。当然,物理层是大粒度的物
理单元,它最终是由粒度更小的组件、模块和进程等单元组成的。
物理架构的应用很广泛。例如,架构设计中可能需要专门说明数
据是如何产生、存储、共享和复制的,这时可以利于物理架构,展示
软件系统在运行期间数据是由哪些运行时单元产生以及是如何产生
的、数据又如何被使用、如何被存储、哪些数据需要跨网络复制和共
享等方面的设计决策。
由此可见,对于“逻辑架构+物理架构”这个“2 视图方法”而
言,组成软件系统的“物理元素”涉及的内容比较宽泛,如图 3-8 所
示。(也正是因为这个原因,设计大型系统的架构时会引入更多架构
设计视图,从而使每个视图的设计内容更加明确,本书后续要讲的5视
图法包含了逻辑架构、开发架构、运行架构、数据架构和物理架
构。)图3-8 “2视图方法”的物理架构可能的设计内容
3.3.3 从“逻辑架构+物理架构”到设计实现
架构设计,指导后续的详细设计和编程;而详细设计和编程,贯
彻和利用这些设计(如图3-9所示):
· 逻辑架构中关于职责划分的决策,体现为层、功能子系统和模
块等的划分决定,从静态视角为详细设计和编程实现提供切实的指
导;有了分解就必然产生协作,逻辑架构还规定了不同逻辑单元之间
的交互接口和交互机制,而编程工作必须实现这些接口和机制。
· 所谓交互机制,是指不同软件单元之间交互的手段。交互机制
的例子有:方法调用、基于RMI的远程方法调用、发送消息等。
· 至于物理架构,它关注的是软件系统在计算机中运行期间的情
况。物理架构设计视图中规定了软件系统如何使用进程和线程完成期
望的并发处理,进程线程这些主动单元(Active Unit)会调用哪些被
动单元(Passive Unit)参与处理,交互机制(如消息)为何等问
题,从而为详细设计和编程实现提供切实指导。图3-9 逻辑架构和物理架构对后续开发的作用
3.4 实际应用(2)——开发人员如何快速成长
3.4.1 开发人员应该多尝试设计
你们公司,你所在的部门,发现了一个问题,即“兵多将少”。
程序员足够多但设计人员太少。
设计不满意似乎成了常态……
诸如相似模块的低水平重复开发等困扰挥之不去……
部门的总体工作效率低下……
你们会也开了,问题也讨论了,问题背后的问题也被“揪”出来
了——开发人员的成长速度低于预期。
怎么办呢?
如果你是程序员,又盼着有一天能做架构师,就要明白“经历设
计在前,成为架构师在后”的道理。也就是说,程序员要尽量找机会
多看看别人的设计成果、多体会别人的设计过程、多试着自己来设计
设计——这些方式都能促进对设计方法或技巧的领会。
如果你是主管,又深感手下“兵多将少”设计人才短缺,就要确
认一下是不是给程序员接触设计的机会太少了。也就是说,主管应该尽量创造机会让程序员多看看别人的设计成果、多体会别人的设计过
程、多试着自己来设计设计。
笔者的经验表明,结合培训、让开发人员对实验项目进行设计,也不失为一种快速提升设计技能的好办法。
3.4.2 实验项目:案例背景、训练目标
下面,我们来设计一个名为MailProxy的邮件代发系统。
众多公司的“客户服务系统”都需要批量地向客户发送邮件。
(“客户服务系统”管理着企业对客户的服务内容,包括客户投诉、故障处理、客户咨询、客户查询、客户回访、客户建议、客户关怀等
服务信息以及服务指标信息等。)而 MailProxy 作为一款软件产品,其核心功能就是:邮件代发。图3-10所示的用例图刻画了MailProxy的
基本功能:
· MailProxy和客户系统对接;
· 通过对Mail Server系统的调度完成自动邮件代发;
· 反馈发送结果给客户系统(含Log日志等);
· 还提供灵活的规则设置等功能。图3-10 MailProxy系统的用例图
“训练”目标:
· 运用本章所讲的“逻辑视图+物理视图”技能。
· 辅以分而治之、迭代式设计两个技巧:
【分而治之】 。逻辑架构进行“逻辑分解”,物理架构进行“物
理分解”,它们分别关注架构的不同方面,利于思维聚焦(相当于化
“大问题”为“子问题”)。
【迭代式设计】 。不同架构视图的设计交替进行、迭代展开。逻
辑职责的划分逐步清晰,促进了物理分布设计;反之亦然(死抠“未
知”抠不出来,就利用当前“已知”探索更多“未知”,循环着来
嘛)。
3.4.3 逻辑架构设计(迭代1)……深入研究需求之后,发现 MailProxy 系统的一个显著特点:
不仅要和“人”交互,更要和多种“外部系统”交互。
因此,设计逻辑架构时,除了包含用户交互层、业务逻辑层、数
据访问层之外,一定应包含一个“系统交互层”(如图3-11所示)。
图3-11 着手设计逻辑架构:分层
3.4.4 物理架构设计(迭代1)
多视图≠多阶段,不应瀑布式地设计每个视图,而是应该迭代式
设计。而且,对大型系统而言,先把逻辑架构详尽地设计完再开始物
理架构的设计,有很大的问题:
· 一是比较困难。毕竟,逻辑架构、物理架构是同一系统的不同
方面;如果系统比较复杂,在对一个方面的设计毫无所知的情况下,过于深入设计的另一方面太过盲目了。
· 二是不利于提高设计质量。而逻辑架构、物理架构交替进行,本身就是不断相互验证、促进设计优化的过程。
应该早些开始物理架构视图的设计。现在,着手设计 MailProxy
的物理分布,如图 3-12所示。图3-12 着手设计物理架构:基本的物理分布
3.4.5 逻辑架构设计(迭代2)
原先接手MailProxy时,对它相当陌生。
设计逻辑架构时,确立了基本分层结构之后就感觉后续设计“展
不开”、“细不下去”。
现在,有了初步的逻辑分层、还有基本的物理分布设计,转回头
来再继续逻辑架构设计试试。……嗯,根据物理架构的提示,逻辑层
“系统交互层”中应该有“Mail Server 交互”模块吧,它封装和具
体 Mail Server 的交互。……嗯,“用户交互层”应当有“设置地
址”、“设置规则”等UI模块。
逐步细化逻辑架构的设计,得到图3-13所示的逻辑架构。图3-13 细化逻辑架构的设计:模块划分
好多逻辑模块呀,把它们划归 3 个工程(Project),这就意味
着 MailProxy 发布时将包含 3个目标程序单元(图3-14描述了3个目
标程序单元的关系):
· 后台服务器程序。
· 管理员Web应用。
· 代理模块(相当于 MailProxy 系统专门发布给合作开发单位
的 API。这样,客户系统只需改动最少的代码就可以与 MailProxy 互
联互通。运行时,客户系统必须包含代理模块的相应Library文件。)图3-14 细化逻辑架构的设计:明确MailProxy包含的程序单元
3.4.6 物理架构设计(迭代2)
继续迭代设计。
上面的逻辑架构设计逐步清晰、不同模块不断明确、相应的目标
程序组件也都清楚了,使你能进一步设计物理架构了。如图 3-15 所
示,软件单元和硬件机器的映射关系进一步明确了,这就为未来的安
装部署方式提供了指导。图3-15 细化物理架构的设计:软件如何部署到硬件
嘿,多个视图之间来回迭代着进行设计,思路清晰、效果不错。第2部分 实践过程篇
第4章 架构设计过程
作为职业软件人,我们都寻求使用一种有效而经济的过程,来建
造一个能够工作的、有用的产品。
——Grady Booch,Rational公司首席科学家
每个项目都是很独特的,因此开发人员必须努力保持微观过程的
非正式性和宏观过程的正式性之间的平衡。
——Grady Booch,《面向对象分析与设计》
程序员向架构师转型,难在何处?难在必须要能开始“试着做起
来”,并慢慢积累感觉,进而积累经验。
“需求决定架构”之所以是一句废话,就是因为它没告诉开发人
员“架构设计怎么做”。
甚至,在没有积累任何经验和“感觉”的情况下,忽然被老板
“委以重任”负责架构设计,都未必是一件好事。因为这次失败了,下次机会就没了。
本章通过下述方式,讲清楚架构设计过程的大局,希望帮助程序
员能将架构设计“试着做起来”:
· 架构设计过程包含哪些步骤?
· 步骤之间什么关系?下游步骤的“输入”依赖的是上游步骤的
哪个“输出”?
4.1 架构设计的实践脉络
4.1.1 洞察节奏:3个原则
成功的架构设计是相似的,失败的架构设计各有各的原因。如下3
个原则也可以被视为做好架构设计的3个必要条件:
· 【原则1】 看透需求· 【原则2】 架构大方向正确
· 【原则3】 设计好架构的各个方面
这3个原则,基本框定了整个架构设计过程的节奏。也就是说(如
图4-1所示):
· 最先,要看透需求,这是基础。架构师可能不是“需求”和
“领域模型”的负责人,但也必须深入了解。
· 中间,确定正确的概念架构。“关键需求”决定“概念架
构”。
· 最后,充分设计架构的各个方面。通过多视图方法“细化架
构”,通过“架构原型”验证架构。
图4-1 架构设计过程的节奏
【原则1】看透需求
架构设计可谓影响深远:一是它决定了系统的整体质量进而决定
了客户的满意度,二是它决定了开发人员开发、维护和扩展程序的容
易程度。
看透需求,简单说就是设计人员要做到“理解了、能说出所以然
来”。必须的!众所周知。
看透需求,不仅要把需求找全,还要把需求项之间的矛盾关系、追溯关系也都搞清楚:· 需求要全。
——举例:重视“功能”忽视“质量”,危险;重视“A 质量”
忽视应有的“B 质量”,危险;忘了来自甲方乙方第三方的“约
束”,危险。功能需求、质量需求、约束需求都要定义清楚。
——处理:发现需求遗漏,就要尽快把遗漏的需求研究清楚。
· 矛盾关系。
——举例:安全性和互操作性有矛盾,可扩展性和性能有矛盾,功能强大和预算有限有矛盾……
——处理:识别出需求间的矛盾还没完,要给对策(例如性能最
重要、可扩展性折衷,或者相反首先照顾可扩展性)、甚至重新评审
需求的合理性。
· 追溯关系。
——举例:“需求范围”合理吗?要向前追溯“系统目标”。符
合目标要求、能帮助实现目标,才合理。
——举例:“用例图”或者“功能项定义”,是否覆盖了更高层
需求之“需求范围”。
——处理:下层需求没有覆盖上层需求,必有需求遗漏。下层需
求超出了上层需求,恐怕存在需求镀金现象。
——说明:一个成功的软件系统,对客户高层而言能够帮助他们
达到业务目标,这些目标就是客户高层眼中的需求;对实际使用系统
的最终用户而言,系统提供的能力能够辅助他们完成日常工作,这些
能力就是最终用户眼中的需求;对开发者而言,有着更多用户没有觉
察到的“需求”要实现……需求是分层次的。
【原则2】架构大方向正确
架构大方向正确是一种策略,先设计概念架构。
一个产品与类似产品在架构上的不同,其实在概念架构设计时就
大局已定了。
它不关注明确的接口定义(之后的细化架构设计才是“模块+接
口”一级的设计),对大型系统而言,这一点恰恰是必需的。概念架构一级的设计更重视“找对路子”,像架构模式啦、集成技术选型
啦……比较策略化。
【原则3】设计好架构的各个方面
架构师必须具备“忘却”的能力,避免涉及太多具体的技术细
节,但是大型软件架构依然是复杂的。这就要求从多个方面进行架构
设计,运用“多视图设计方法”:
· 例如,为了满足性能、持续可用性等方面的需求,架构师必须
深入研究软件系统运行期间的情况,权衡轻重缓急,并制定相应的并
行、分时、排队、缓存和批处理等设计决策。(运行架构视图)
· 而要满足可扩展性、可重用性等方面的需求,则要求架构师深
入研究软件系统开发期间的代码文件组织、变化隔离和框架使用等情
况,制定相应的设计决策。(开发架构视图)
·……本书推荐5视图方法:逻辑视图、开发视图、物理视图、运
行视图、数据视图。
实际经验表明,越是复杂的系统,越需要从多个方面进行架构设
计,这样才能把问题研究和表达清楚。Grady Booch 在其著作《UML
用户指南》中指出:“如果选择视图的工作没有做好,或者以牺牲其
他视图为代价只注重一个视图,就会冒掩盖问题以及延误解决问题
(这里的问题是指那些最终会导致失败的问题)的风险。”
【强调】培训中发现的问题(关于原则2)
笔者在和企业的深入接触中发现,项目经理、架构师和总工等角
色“最深有感慨”的就是“架构大方向正确”原则,但很多程序开发
人员对此则“感触不深”。在此,希望程序开发人员稍微留意,概念
架构是直指系统设计目标的设计思想和重大选择——是关乎任何复杂
系统成败的最关键的、指向性的设计:
· 你作为架构师,设计大中型系统的架构时,会先对比分析几种
可能的概念架构。
· 看看竞争对手的产品彩页,上面印的架构图,还是概念架构。
· 如果你是售前,你又提到架构,这也是概念架构。
· 如果你去投标,你讲的架构,就是概念架构。架构新手和有经验架构师的区别之一,在于是否懂得、并能有效
地进行概念架构的设计。作为架构新手,尤其害怕碰上自己没做过的
系统;系统较大时,一旦祭出“架构=模块+接口”的法宝却不太奏
效,架构新手就往往乱了阵脚。相反,有经验的架构师不会一上来就
关注如何定义“接口”,他们在大型系统架构设计的早期比较注重识
别 1)重大需求、2)特色需求、3)高风险需求,据此来决定如何划
分顶级子系统、采用什么架构风格和开发技术、集成是否要支持、二
次开发是否要支持。
4.1.2 掌握过程:6个步骤
洞察了架构设计过程的节奏,再看步骤。整个架构设计过程,包
含 6 大步骤(如图 4-2所示):
(1)需求分析
(2)领域建模
(3)确定关键需求
(4)概念架构设计
(5)细化架构设计
(6)架构验证
至此,6步骤之间的关系也就不难理解了,如图4-3所示。
可以看出,架构设计的开展非常依赖其上游活动。总体而言,这
些上游活动包括需求分析和领域建模。图4-2 架构设计过程的6个步骤
图4-3 6个步骤之间的关系
需求分析。 毋庸置疑,在没有全面认识需求并权衡不同需求之间
相互影响的情况下,设计出的架构很可能有问题。
领域建模。 领域建模的目的是:透过问题领域的重重现象,捕捉
其背后最为稳固的领域概念,以及这些概念之间的关系。在项目前
期,所建立的领域模型将为所有团队成员之间、团队成员和客户之间
的交流提供共同认可的语言核心。随着项目的进展,领域模型不断被
精化,最终成为整个软件的问题领域层,该层决定了软件系统能力的范围。本书还认为,从项目前期伊始,软件架构师就应该是领域建模
活动的领导者,这样可以避免“不同阶段领域模型由不同人负责”所
带来的问题。
接下来要进行概念架构的设计。软件系统的规模越大、复杂程度
越高,进行概念架构设计的好处就越明显。
确定对架构关键的需求。 这不仅要求对功能需求(如用例)进
行筛选,还要对非功能需求进行综合权衡,最终确定对软件架构起关
键作用的需求子集。
概念架构设计。 概念架构的设计,必须同时重视关键功能和关键
质量。业界流行的一种错误观点是“概念架构=理想化架构”,不考虑
任何非功能需求,也不考虑任何具体技术。本书提出,概念架构要明
确给出“1 个决定 4 个选型”,即决定:1)如何划分顶级子系统;
2)架构风格选型;3)开发技术选型;4)集成技术选型;5)二次开
发技术选型。可以看出,其中涉及多项重大技术选型。
在接下来,全面展开规格级的架构设计工作,设计出能实际指导
团队并行开发的细化架构。
细化架构设计。 一般而言,可以分别从逻辑架构、开发架构、运
行架构、物理架构、数据架构等不同架构视图进行设计。
架构验证。 对后续工作产生重大影响返工代价很高的任何工作都
应该进行验证,软件需求如此,架构设计方案也是如此。至于验证架
构的手段,对软件项目而言,往往需要开发出架构原型,并对原型进
行测试和评审来达到;而对软件产品而言,可以开发一个框架
(Framework)来贯彻架构设计方案,再通过在框架之上开发特定的垂
直原型来验证特定的功能或质量属性。因此,从架构验证工作得到的
不应该仅仅是“软件架构是否有效”的回答,还必须有可实际运行的
程序:体现软件架构的垂直抛弃原型或垂直演进原型,或者是更利于
重用的框架。这些成果为后续的开发提供了实在的支持。
在通过后续各章展开讨论这些工作步骤之前,通过“速查手册”
的形式,再总体归纳一下每个工作步骤的主要输入、输出、关键技能
项。
4.2 架构设计的速查手册下面对架构设计的每个步骤,进行总括描述,供读者在“付诸实
践”时参考。
笔者建议,在系统地学习了第5~15章之后,请复习本节。本节所
采用的这种形式,也是笔者在架构培训的“总结回顾”环节所经常采
用的。效果不错!
4.2.1 需求分析
需求分析,是很多活动的统称,它是本书“架构设计过程”中第
1 个大的工作步骤。如图4-4所示。
需求分析活动输出的“需求”,必须涵盖功能、质量、约束这三
个方面,这些是后续设计活动所需要的。需求分析工作涉及的“技能
项”较多,总体而言可总结为“两纵三横”,如图 4-5所示:
· 【一纵】 需求沟通。持续伴随需求分析过程的,是需求沟
通、需求启发、需求验证等活动,这些活动都要求需方和开发方紧密
协同、精诚合作。“闭门造需”危险大了。
· 【二纵】 非功能需求的确定。真实的实践中,确定非功能需
求是一个持续的过程,是持久战。究其原因,这是非功能需求的范围
广造成的,无论是技术还是业务、无论是甲方还是乙方,都可能有这
样那样的非功能需求。想“一蹴而就”地定义非功能需求是不现实
的。图4-4 需求分析的“位置”
· 【三横】 需求分析主线。从确定系统目标开始,后续凭借
“范围+Feature+上下文图”三剑客研究高层需求,再后续建立开发人
员较熟悉的用例模型。
图4-5 需求分析的“技能项”和“输出”
做不到“追根溯源”的需求分析,往往会失败。因此,我们补充
图 4-6 来强调需求分析工作的主线是“确定系统目标→研究高层需求
→建立用例模型”,需求从“高飘”到“落地”,成果项从“目标列表”到“范围框图+Feature 树+上下文图”到“用例图+用例规约”,需求跟踪脉络清晰可辨。
更多内容,请阅读本书讲需求分析的章:第5章,需求分析;第6
章,用例与需求。
4.2.2 领域建模
领域建模,是以提炼领域概念,建立领域模型为目的的活动。领
域建模实践的精髓是“业务决定功能,功能决定模型”,理解了这个
理念,评审领域模型也变得再自然不过了。如图 4-7所示。
图4-6 需求分析的主线体现“追根溯源”图4-7 领域建模的“位置”
领域建模活动的输入:一是“功能”,二是“可扩展性”具体要
求(如图 4-8 所示)。说到底,都是“功能”,因为领域模型必须能
支持在《软件需求规格说明书》中规定的“现在的功能”,还应该支
持随着业务发展而出现的“未来的功能”。这两种功能,就是驱动领
域建模的因素,以及评审领域模型的依据。
更多内容,请阅读本书讲领域建模的章:第7章,领域建模。
4.2.3 确定关键需求
架构面前所有需求一律平等?不可能。
关键需求决定了架构的大方向。图4-9显示了确定关键需求工作的
位置。图4-8 领域建模的“输入”和“输出”
图4-9 确定关键需求的“位置”
具体而言,为了确定“关键功能”,一要关注“功能需求”,二
要研究“约束需求”;为了确定“关键质量”,一要关注“质量需
求”,二要研究“约束需求”。如图4-10所示。图4-10 确定关键需求的“输入”、“技能项”和“输出”
大系统架构与小系统架构的设计为什么不同?你的系统架构与别
人的系统架构设计为什么不同?……探究架构设计的整个过程,“关
键需求的确定”这一步是“分水岭”。
更多内容,请阅读本书讲确定关键需求的章:第8章,确定关键需
求。
4.2.4 概念架构设计
概念架构是高层架构成果的核心,框定了架构大方向,是甲方规
划、乙方投标的评定关键。如图4-11所示。图4-11 概念架构设计的“位置”
本书给出的定义,所谓概念架构,是直指系统目标的设计思想、重大选择。“直指目标”说的是输入,“设计思想和重大选择”说的
是输出。如图4-12所示。
图4-12 概念架构设计的“输入”、“技能项”和“输出”
· 概念架构设计要“直指”的、以之为输入的,就是“关键需
求”。
· 针对不同需求(功能或者质量),需要运用不同“技能项”,鲁棒图建模、目标-场景-决策表,非常实用。· 概念架构设计的“输出”是“1个决定、4个选择”:
1)决定如何划分顶级子系统;
2)架构风格选型;
3)开发技术选型;
4)二次开发技术选型;
5)集成技术选型。
更多内容,请阅读本书讲概念架构设计的章:第9章,概念架构设
计。
4.2.5 细化架构设计
细化架构和概念架构的关键区别之一是:概念架构没有设计到
“模块+接口”一级,而细化架构必须关注“模块+接口”。图4-13所
示为细化架构设计的“位置”。
图4-13 细化架构设计的“位置”
众所周知,架构设计涉及的方面很广(模块切分、持久化格式、并行并发等都得管),架构设计师得是通才(要掌握的技能项较
多)。对此,细化架构设计这一步体现得最充分,图 4-14 列出了细
化架构设计的5个设计视图、15个设计任务。题4-14 细化架构设计的“技能项”——15个设计任务
再关注上游对细化架构设计的影响、支持。细化架构设计的输入
既来自“需求成果”层面、也来自“高层架构”层面,如图4-15所
示。
· 细化架构要为“需求”而设计。关键对比:概念架构设计的输
入是“关键需求”、而不是泛泛的所有“需求”。
· 细化架构要在“概念架构”的设计思想下进行。
· “领域模型”,一方面影响着“逻辑架构视图”的“领域模型
设计”,另一方面影响着“数据架构视图”的“存储格式设计”。图4-15 细化架构设计的“输入”和“输出”
更多内容,请阅读本书讲细化架构设计的章:
· 第10章,细化架构设计。
· 第12章,粗粒度“功能模块”划分。
· 第13章,如何分层。
· 第14章,用例驱动的模块划分过程。
· 第15章,模块划分的4步骤方法——运用层、模块、功能模
块、用例驱动。
4.2.6 架构验证
如有必要,需要进行架构验证。如图4-16所示。
架构验证的输出成果是“架构原型”。和一般的开发不同,架构
原型的开发不是要完美地、无 Bug 地实现功能,而是在“细化架构”
的总体指导下,仅把存在“风险”的那些设计尽早开发出来,然后通
过执行测试等手段判断“风险”是否解决,如图4-17所示。
更多内容,请阅读本书讲架构验证的章:第11章,架构验证。图4-16 架构验证的“位置”
图4-17 架构验证的“输入”和“输出”第5章 需求分析
对于需求分析员而言,真正的专业主义是基于业务利益(解决问
题、创造机会、提高管控力等)的沟通。
——徐锋,《软件需求最佳实践》
当前业界,大多数架构师都认同“需求决定架构”,但对需求
“如何决定”架构还知之不深。……不同需求影响架构的不同原理,才是架构设计思维的基础。
——温昱,《一线架构师实践指南》
一个程序员,在向架构师转型的道路上,一定“绕”不过软件需
求的问题。本章立足软件开发人员的视角,逐次讨论:
· 需求怎么来的?(需求开发=愿景分析+需求分析)
· 如何判断掌握的需求全不全?(功能、质量、约束三类需求都
不能漏)
· 从需求向设计转化的关键思维是什么?(功能、质量、约束影
响架构的不同原理是核心)
5.1 需求开发(上)——愿景分析
我们从“整体过程”入手,然后聚焦讨论“愿景”和“愿景分
析”。
5.1.1 从概念化阶段说起
图 5-1 所示为软件研发与交付过程总图,包含概念化阶段、需求
分析阶段、架构设计阶段、并行开发与测试阶段、验收与交付阶段,共5个阶段。图5-1 软件研发与交付过程总图
随着研发类型的不同(项目、产品、或解决方案),概念化阶段
包含的工作重点有所不同,但主要内容都包括:
· 愿景分析。
· 风险评估。
· 可行性分析。
· 项目进度和成本的粗略预估。
下面聚焦讨论“愿景”。
5.1.2 愿景愿景分析,要解决项目、产品或解决方案的起源问题。所谓明确
愿景,就是针对系统目标、主要特性、功能范围和成功要素等进行构
思并达成一致。
对定制开发的软件项目来说,愿景分析可由需方或者软件供应商
来组织,一般建议由需方高层领导牵头,愿景分析过程中需方人员也
必须全程积极参与。而对产品型的软件公司来说,往往是产品管理部
门根据市场部门的要求,进行愿景分析、定义产品所要提供的业务功
能。无论上述哪种情况,愿景分析都应阐明业务需求、描述需求产生
的背景和理由等。
愿景分析最重要的工作成果是《愿景与范围文档》。记得有一位
大师,当被问及“如果软件开发中只能有一份文档,应当是哪一份”
时,他毫不犹豫地回答说是《愿景文档》。由此可见《愿景与范围文
档》的重要性。
典型的《愿景与范围文档》包括下列内容:
1.业务需求
a) 背景
b) 业务机遇
c) 业务目标
d) 客户或市场需求
e) 提供给客户的价值
f) 业务风险
2.项目愿景的解决方案
a) 项目愿景陈述
b) 主要特征
c) 假设和依赖环境
3.范围和局限性
a) 首次发布的范围
b) 随后发布的范围
c) 局限性和专用性4.业务环境
a) 客户概貌
b) 项目的优先级
5.产品成功的因素
在此有必要指出,你可能在不同类型的软件企业工作(例如项目
型公司、产品型公司、外包型公司、服务型公司等),于是,由于偏
重内容有所不同,你所在的企业对《愿景与范围文档》其实有着不同
的叫法。例如:
· 有 的 产 品 型 公 司 , 称 为 《 市 场 需 求 文 档 》 ( Market
Requirements Document,MRD);
· 有的产品型公司,称为《产品需求文档》(Product
Requirements Document,PRD);
· 有的以做项目为主的公司,称为《项目立项书》。
5.1.3 上下文图
在《愿景与范围文档》中,上下文图(Context Diagram)扮演着
重要角色。
上下文图是一种“辅助说明”需求范围(Scope)的方式,它清晰
地描述了待开发系统与周围所有事物之间的界限与联系。上下文图可
以由市场部门绘制(画法相对随意例如利用PowerPoint),也可以由
架构师来绘制(推荐UML用例图的顶级视图)。
下面我们举例,看到实际的上下文图,能让我们更“实在”地理
解什么是一个系统的愿景。
【案例1】银行“综合前置系统”的上下文图
例如,你所在的银行开发中心,要研制综合前置系统。
图 5-2 展示了银行综合前置系统的上下文图,从一个方面“描
绘”了愿景。首先,我们看到要研发的综合前置系统在上下文图中还
是个黑盒子,里面的组成并不清楚,否则就不是上下文图了。其次,我们通过上下文图理清了和综合前置黑盒子有关联的4类系统,分别是
主机、外挂、第三方、渠道。图5-2 银行综合前置系统的上下文图
【对比1】总体架构的物理视图(不是上下文图,也不是“综
合前置系统”的)
上下文图之所以非常有用,关键在于它以“待研发的系统”为中
心。对此,Kossiakoff 有如此论述:
待研发系统位于上下文图的中心,所有和待研发系统有关联关系
的系统、环境和活动围绕在它的周围。但是,上下文图不提供系统内
部结构的任何信息。上下文图的目的是通过明确系统相关的外部因素
和事件,促进更完整地识别系统需求和约束(pictures the sy stem
at the cent er,with no deta ils of its interior structure,surrounded by all its interacting systems,envir onment and
ac tivities.The obj ective of a sy stem cont ext diagram is
to f ocus att ention on external fac tors and ev ents thatshoul d be consid ered i n developing a complete set of
system requirements and constraints)。
本书将上下文图的要点归纳为两点:
· 内容原则 。关注本系统,以及和本系统有关联的因素,但不
关注本系统内部——既不关注内部功能,也不关注内部结构。
· 形式原则 。明确标识出要研发的是什么系统,保持它为黑
盒,将它画在上下文图的中央位置,其他相关因素环绕周围。
回顾图 5-2,它就是以“综合前置系统”为中心的上下文图,满
足上述“内容原则”和“形式原则”。
对比图5-3:
· 内容 。该图是整个“银行核心系统”,而不是“综合前
置”。“综合前置”只是整个“银行核心系统”的一部分。
· 形式 。该图不是以“中心+四周”形式组织的。
· 结论 。该图不是“综合前置系统”的上下文图,而是银行核
心系统的总体架构图(物理视图)。
【对比2】银行“综合前置系统”的架构图(不是上下文图)
作为对比,再看图 5-4,它是综合前置系统的架构图(属于设
计),而不是上下文图(说明需求范围)。图中表达的架构级设计决
策包含:
· 首先,中心前置业务平台和分行前置业务平台,是综合前置的
核心,分别部署在总行数据中心和每家分行的运行中心。
· 为了支持网上银行,综合前置中包含网银接入平台,在总行一
级部署、连接到中心前置业务平台。
· 和网上银行的“由总行一级统一支持”方式不同,综合前置为
了支持电话银行而包含了电话接入前置平台,在每家分行一级部署、连接到分行前置业务平台。
·……综合前置还包括核心系统的连接、自助设备接入、RA前置
机等设计。
· 综合前置与人民银行系统互联、还与代理商户互联,具体设计
策略有何不同吗?综合前置的分行前置业务平台,负责和当地人民银行,以及当地
代理商户互联;
如果不是当地代理商户、而是中心级代理商户,应直接和综合前
置的中心前置业务平台互联;
人民银行总中心,直接和综合前置的中心前置业务平台互联。图5-3 银行核心系统的总体架构图(物理视图)
(图片来源:http:www.cbinews.comsolutionnews2187.html)【案例2】对讲机软件:上下文图vs.用例图
再例如,你是一个嵌入式软件架构师,你要负责的是对讲机内的
软件。
图 5-5 分别展示了对讲机的上下文图,以及用例图(用于对
比)。图中的上下文图采用了“用例图风格”来画,现在用例技术很
流行所以笔者推荐这种画法,但注意它并不等同于“用例图”。区别
的关键是,用例图刻画了“对讲机”提供的各种功能,而“用例图风
格”的上下文图没有刻画功能。正如笔者前文所述的上下文图“内容
原则”:上下文图“不关注本系统内部——既不关注内部功能,也不
关注内部结构”。
图5-4 银行综合前置系统的基本架构图图5-5 对讲机:上下文图vs.用例图
总之,上下文图可以明确:1)哪个系统是待研发的软件系统;
2)哪些方面在软件系统之外;3)谁使用该系统;4)此软件系统需要
和哪些相关软件系统进行交互。
5.1.4 愿景分析实践要领
愿景分析,换个角度讲就是我们常说的需求调研(愿景分析的说
法重目标,需求调研的说法重活动)。为了便于掌握实践要领,本书
推荐这样一个务实的公式,如图5-6所示:
愿景=业务目标+范围+Feature+上下文图图5-6 愿景=业务目标+范围+Feature+上下文图
范围(Scope)、Feature、上下文图是刻画高层需求的“三剑
客”,常用,好用!图 5-7 再次描述了这三种技术的定位,以及它们
和系统业务目标的关系。
图5-7 业务目标、范围、Feature、上下文图的关系
5.2 需求开发(下)——需求分析什么是软件需求?简单地说,软件需求就是“这个软件到底要为
用户做什么”。
IEEE的软件工程标准术语表将需求定义为:
1.用户所需的解决某个问题或达到某个目标所要具备的条件或能
力。
2.系统或系统组件为符合合同、标准、规范或其他正式文档而必
须满足的条件或必须具备的能力。
3.上述第一项或第二项中定义的条件和能力的文档表述。
而RUP是这样定义需求的:
需求描述了系统必须满足的情况或提供的能力,它就可以是直接
来自客户需要,也可以来自合同、标准、规范或其他有正规约束力的
文档(A require ment describes a condition or either derived
directly fro m user needs,or stated in a contract,standar
d,specification,or other formally imposed document.)。
架构师必须懂需求吗?是的。
架构师岗位本身,并不负责需求分析,但对需求分析的工作过程
一定要了解。
5.2.1 需求捕获vs.需求分析vs.系统分析
从软件过程全局看,需求分析是一个承上启下的阶段——“上
承”愿景,“下接”设计。上游,进行愿景分析、研究可行性、输出
《愿景与范围文档》,需求分析要进一步完善和细化软件需求。后
续,要进行的设计活动,以需求分析活动定义的功能需求、质量属性
需求以及约束性需求等为基本参考。
我们经常说的“需求分析”工作、经常被称为的“需求分析员”
岗位,其背后其实涉及的活动包含:
· 需求捕获。
· 需求分析。
· 系统分析。需求捕获是获取知识的过程,知识从无到有、从少到多。需求采
集者必须理解用户所从事的工作,并且了解用户和客户希望软件系统
在哪些方面帮助他们。
需求分析是挖掘和整理知识的过程,它在已掌握知识的基础上进
行。毕竟,初步捕获到的需求信息往往处于不同层次,也有一些主观
甚至不正确的信息。而经过必要的需求分析工作之后,需求会更加系
统、更加有条理、更加全面。
那么系统分析呢?如果说,需求分析致力于搞清楚软件系统要
“做什么”的话,那么系统分析已经开始涉及“怎么做”的问题了。
《系统分析》一书中写道:
简单地说,系统分析的意义如下:“系统分析是针对系统所要面
临的问题,搜集相关的资料,以了解产生问题的原因所在,进而提出
解决问题的方法与可行的逻辑方案,以满足系统的需求,实现预定的
目标。”
【实际问题1】将需求捕获和需求分析视为两个阶段,这是错
误的
需求捕获、需求分析以及系统分析是相互伴随、交叉进行的(如
图5-8所示):
· 需求工作伊始,更多进行需求捕获,需求分析工作偏少;
· 随着掌握的需求信息越来越多,对需求的分析才可能越来越
多;
· 世界不是“问题—解决方案”这么简单的模型,是“问题—解
决方案—衍生问题—解决方案—……”才现实——上一级的解决方案
对下一级就意味着“待解决的问题”。于是,需求分析连带出更多系
统分析的工作非常正常。图5-8 需求捕获、需求分析与系统分析
将需求捕获和需求分析视为两个阶段,这是错误的。例如,图 5-
9 来自某企业的《需求开发过程》规范,就将“获取需求”和“分析
需求”定义成了两个阶段。这种“捕获得到全部需求,之后再集中进
行分析”的做法不务实、效果差、容易引起大量需求变更。
图5-9 错误的需求开发过程(来自某企业的《需求开发过程》规范)
【实际问题2】需求分析与系统分析混淆实践中,需求分析和系统分析常被混淆。一位技术经理,就不无
困惑地问过我:“我们公司的需求分析员提交的《系统需求文档》里
面有一节叫‘系统分析’,但内容都是系统设计的,好像明显在和我
这个架构师‘争功’,真不知该怎么办?”
为了不再混淆这两者,应明确:
· 需求分析,是搞清楚系统“做什么”。
· 系统分析,关注系统“怎么做”。更直白地说,系统分析 ≈
初步的高层设计。
· 很多开发者对OOA心存困惑。其实,OOA是一种“系统分析”技
能,对很多“需求分析”内容并不涵盖。认为掌握了 OOA 就能做需求
分析了,结果会“死得很难看”。
对此,邵维忠教授和杨芙清院士在《面向对象的系统设计》中有
过精彩论述:
用“做什么”和“怎么做”来区分分析与设计,是从结构化方法
沿袭过来的一种观点。但即使在结构化方法中这种说法也很勉强……
在“做什么”和“怎么做”的问题上为什么会出现上述矛盾?究
其根源,在于人们对软件工程中“分析”这个术语的含义有着不同的
理解——有时把它作为需求分析(Requirements Analy sis)的简
称,有时是指系统分析(Systems An alysis),有时则作为需求分析
和系统分析的总称。
需求分析是软件工程学中的经典的术语之一,名副其实的含义应
是对用户需求进行分析,旨在产生一份明确、规范的需求定义。从这
个意义上讲,“分析是解决做什么而不是解决怎么做的问题”是无可
挑剔的。
但迄今为止人们所提出的各种分析方法(包括结构化分析和面向
对象分析)中,真正属于需求分析的内容所占的分量并不太大;更多
的内容是给出一种系统建模方法(包括一种表示法和相应的建模过程
指导),告诉分析员如何建立一个能够满足(由需求定义所描述的)
用户需求的系统模型。分析员大量的工作是对系统的应用领域进行调
查和研究并抽象地表示这个系统。确切地讲,这些工作应该叫做系统分析,而不是需求分析。它既是对“做什么”问题的进一步明确,也
在相当程度上涉及“怎么做”的问题。
忽略分析、需求分析和系统分析这些术语的不同含义,并在讨论
中将它们随意替换,是造成上述矛盾的根源。
5.2.2 需求捕获及成果
典型的需求捕获的工作成果是一摞“需求采集卡”(如表 5-1 所
示),其中记录了需求类型、需求描述、需求背景、需求提出者和需
求记录者等对进一步的需求分析非常有用的信息。
表5-1 需求采集卡
5.2.3 需求分析及成果
用例技术要登场了。
通过需求采集活动,我们捕获到了大量“原始需求”,而需求分
析则对采集到的原始需求进行分析、整理、辨别和归纳,最终形成系
统的、明确的软件需求。
需求分析应交付一份明确的、规范的需求定义——《软件需求规
格说明书》(Software Requirements Specification,SRS)。
《SRS》精确地阐述了一个软件系统必须提供的功能、必须达到的质量
属性指标,以及它必须遵守的约束。其中,当前最常用的是用例(Use
Cas e)技术,用例图“立足整个系统”刻画系统能为外部用户或系统
提供的服务,用例规约“聚焦每个功能”刻画系统应提供的具体行为。因为《SRS》应尽可能完整地描述各种条件下的系统行为,所以重
点用例的用例规约要将多种可能的“意外情况”描述出来。
续表5.2.4 系统分析及成果
对于不同的系统分析方法,其工作成果差异很大。通过结构化分
析方法得到的最重要的工作成果是数据流图,而面向对象的系统分析
方法得到的工作成果主要是分析类图、鲁棒图、序列图等——其中分
析类图描述设计的静态方面,而鲁棒图和序列图描述设计的动态方
面。
5.3 掌握的需求全不全
架构师需要全面了解需求吗?是的。观念是行为的“向导”,有
怎样的观念存在,就有怎样的行为方式产生——“观念突破”的意义
就在于此。
程序员向架构师转型时,需求列表这种观念需要突破:
· 作为程序员 ,“你”经常目睹下面这一切:项目经理打开
Excel 表格,根据“Feature List”分配工作,一个程序员负责实现
几项,倍儿清楚。如此种种,使“你”确信需求就是列表(List)。
· 作为从程序员成功转型的架构师 ,“你”会关注功能需求、质量、约束等各种需求类别,更不希望因为没有“需求大局观”而造成需求遗漏。这时,需求列表对“你”架构设计工作的支持已经捉襟
见肘。
5.3.1 二维需求观与ADMEMS矩阵
突破“需求列表”思维,应以“二维需求观”来看待需求(如图
5-10所示)。
首先,需求是分层次的 。本质上,我们是根据“不同层次的涉
众提出需求所站的不同立场”,将需求划分为三个层次。其实,为了
便于需求跟踪(核心是跟踪需求来源),我们也必然要这么做。
· 组织级需求 。包含客户或出资者要达到的业务目标、预期投
资、工期要求,以及要符合哪些标准、对哪些遗留系统进行整合等约
束条件。
· 用户级需求 。用户使用系统来辅助完成哪些工作?对质量有
何要求?用户群及所处的使用环境方面有何特殊要求?
· 开发级需求 。开发人员需要实现什么?开发期间、维护期间
有何质量考虑?开发团队的哪些情况会反过来影响架构?
图5-10 二维需求观
其次,需求还必须从不同方面进行考虑 。实践一再表明,忽视
质量属性和约束性需求,常常导致架构设计最终失败。例如,一个网上书店系统:
· “浏览书目”、“下订单”、“跟踪订单状态”以及“为书籍
打分”等,属功能需求。
· 系统应当有良好的“互操作性”和“安全性”,这是质量属性
需求。
· 系统“必须运行于Linux平台之上”,则属于约束性需求之
列。
也就是说,从“直接目标还是间接限制”的角度把需求分为三
类。
· 功能需求:更多体现各级直接目标要求。
· 质量属性:运行期质量+开发期质量。
· 约束需求:业务环境因素+使用环境因素+构建环境因素+技术
环境因素。
作为设计人员,经常问的一个问题是:我掌握的需求全不全,有
没有遗漏?
《一线架构师实践指南》一书提出的 ADMEMS 矩阵(又称“需求
层次-需求方面矩阵”)可以作为需求梳理和需求评审的工具,以一种
直观易行的“Checklist思维”帮助设计人员全面梳理和评价需求,如
图5-11所示。
5.3.2 功能
功能需求是我们最熟悉的一类需求,它描述系统“应该做什
么”。如果采用比较简单的方式,可以在《软件需求规格说明书》中
逐个列举每个功能项、进行简要说明,如表 5-2所示。图5-11 ADMEMS矩阵(需求层次—需求方面矩阵)
表5-2 功能描述示例(一卡通系统功能描述的一小部分)
如果采用比较正规的方式,可以在《软件需求规格说明书》中将
每项功能的用户类、用户输入或系统外激励、系统动作(本项和前一
项相当于用例规约的主事件流)、业务规则、例外及相应处理(本项相当于用例规约的备选事件流)、特殊需求或限定、相关功能、注释
和说明等内容进行展开说明,如表5-3所示。
表5-3 功能描述示例(CRM的修改客户联系人资料功能)
续表
5.3.3 质量
下面重点讨论非功能需求中的质量属性需求。
如何给众多质量属性分类,这是一个问题。McCall 等人于 1977
年提出的软件质量属性的分类模型,影响非常广泛。如图 5-12 所示,它将软件的质量属性划分为三大类:产品操作、产品修改、产品
改型。
图5-12 McCall等人提出的软件质量属性的分类模型
该分类方法相当经典,但似乎缺少了“产品开发”类的质量属性
——诸如易理解性、可扩展性和可重用性等。另一方面,我们也发现
产品开发、产品修改和产品改型这三类质量属性有重叠(如易理解性
和可扩展性对开发和维护都很重要,再如对产品改型很关键的可重用
性也同样影响着产品开发)。因此,考虑到被广泛认同的迭代式开发
所暗示的增量交付使开发、修改和维护之间的界限不再像以前那么明
显,所以本书认为有充分的理由将产品开发、产品修改和产品改型这
三类质量属性合并为一类。
本书推荐将软件质量属性划分为运行期质量属性和开发期质量属
性两大类(如表 5-4 所示):
· 开发期质量属性其实包含了和软件开发、维护和移植这三类活
动相关的所有质量属性,可以说这里的“开发”是相当广义的;
· 开发期质量属性是开发人员、开发管理人员和维护人员都非常
关心的,对最终用户而言,这些质量属性只是间接地促进用户需求的
满足;· 运行期质量属性是软件系统在运行期间,最终用户可以直接感
受到的一类属性,这些质量属性直接影响着用户对软件产品的满意
度。
表5-4 推荐的软件质量属性分类方式
运行期质量属性需求是一类非常重要的非功能需求,对客户满意
度非常关键,下面一一进行说明。
性能 (Performance)。性能是指软件系统及时提供相应服务的
能力。具体而言,性能包括速度、吞吐量和持续高速性三方面的要
求:
· 吞吐量通过单位时间处理的交易数来度量;
· 速度往往通过平均响应时间来度量;
· 而持续高速性是指保持高速处理速度的能力。
持续高速性和实时系统有关,实时系统有“硬实时”和“软实
时”之分,其中硬实时系统对每次系统响应时间都有严格要求,如果
不能满足要求,后果将是致命的,所以把性能笼统地说成“进行典型
操作所需的时间”显然忽视了实时系统性能的内涵。
下面值得说明效率(Efficiency)和性能的关系:它们反映了同
一问题的“表”、“里”两面,性能为“表”,效率为“里”,如图
5-13 所示。所谓效率,是指软件系统对各种资源(CPU、内存、硬盘
存储、硬盘IO、网络带宽等)的使用效率。安全性 (Security)。安全性指软件系统同时兼顾向合法用户提
供服务,以及阻止非授权使用的能力。高安全性意味着“同时兼
顾”,这是因为有些攻击的目的是使软件系统拒绝向合法用户提供服
务,而不是非法访问。
易用性 (Usability)。不少文献也称之为可用性,但为了避免
和持续可用性(Availability)混淆,本书采用非常流行的“易用
性”的叫法。指软件系统易于使用的程度。
图5-13 性能和效率的关系
持续可用性 (Availability)。不少文献也称之为可用性,但为
了避免和易用性(Usability)混淆,本书采用“持续可用性”的叫
法。持续可用性指系统长时间无故障运行的能力。可伸缩性 (Scalability)。可伸缩性指当用户数和数据量增加
时,软件系统维持高服务质量的能力。例如当业务量较小时,软件系
统运行在一台服务器上,当业务量增大时,可以通过增加服务器或增
加单台服务器上所运行软件系统的个数来提高性能,而无需对软件系
统本身进行编程级的修改。
互操作性 (Interoperability)。可操作性指本软件系统与其他
系统交换数据和相互调用服务的难易程度。
可靠性 (Reliability)。软件系统在一定的时间内无故障运行
的能力。
鲁棒性 (Robustness)。鲁棒性也称健壮性、容错性。鲁棒性是
指软件系统在以下情况下仍能够正常运行的能力:用户进行了非法操
作;相连的软硬件系统发生了故障,以及其他非正常情况。
而开发期质量属性则随着软件系统规模的日益增长,显得越来越
重要了,下面一一说明之。
易理解性 (Understandability)。尤指设计被开发人员理解的
难易程度。
可扩展性 (Extensibility)。可扩展性是指为适应新需求或需
求的变化为软件增加功能的能力。我们在实际工作中,经常将可扩展
性称为灵活性。
可重用性 (Reusability)。可重用性是指重用软件系统或其一
部分能力的难易程度。
可测试性 (Testability)。可测试性是指对软件测试以证明其
满足需求规约的难易程度。在实际工作中主要指进行单元测试、插桩
测试等的难易程度。
可维护性 (Maintainability)。可维护性是指为了达到下列三
种目的之一而定位修改点并实施修改的难易程度:修改Bug;增加功
能;提高质量属性。
可移植性 (Portability)。可移植性是指将软件系统从一个运
行环境转移到另一个不同的运行环境的难易程度。
务实地,我们可以将运行期质量属性和功能性一起视为“软件的
外部质量”,而将开发期质量属性视为“软件的内部质量”。无疑,软件的内部质量制约着软件的外部质量;在软件开发管理本身已经十
分复杂的今天,想使内部质量很差的软件具有良好的外部质量几乎是
不可能的。同时,随着商业环境变化的加剧,很多企业软件出现了
“建成即废弃”的尴尬情况。于是,软件系统的内部品质越来越受到
重视,通过强化软件系统的可扩展性、可重用性、易理解性等开发期
质量属性,可以使软件有更多被改变、被重用的空间。
5.3.4 约束
业界对约束一直不够重视,例如《UML 和模式应用(第 2 版)》
一书对约束的理解就太简单了:
约束 不是行为,是设计或项目的某些限制条件。这些限制条件也
属于需求,但通常被称为“约束”来强调其限制性。例如:
· 必须使用Oracle(我们硬件签署过使用许可证了);
· 必须在Linux上运行(成本低)。
笔者在《一线架构师实践指南》一书中做了梳理总结:
约束需求=业务环境因素+使用环境因素+构建环境因素+技术环境
因素。
第一,业务环境因素(来自客户或出资方的约束性需求)。
· 架构师必须充分考虑客户对上线时间的要求、预算限制、以及
集成需要等非功能需求。
· 客户所处的业务领域为哪些?有什么业务规则和业务限制?
· 是否需要关注相应的法律法规、专利限制?
·……
第二,使用环境因素(来自用户的约束性需求)。
· 软件将提供给何阶层用户?
· 用户的年龄段及使用偏好是哪些?
· 用户是否遍及多个国家?
· 使用期间的环境有电磁干扰、车船移动等因素吗?
·……第三,构建环境因素(来自开发者和升级维护人员的约束性需
求)。
· 开发团队的技术水平如果有限(有些软件企业甚至希望通过招
聘便宜的程序员来降低成本)、磨合程度不高、分布在不同城市,会
有何影响?
· 开发管理方面、源代码保密方面,是否需要顾及?
·……
第四,技术环境因素(也不能遗忘,业界当前技术环境本身也是
约束性需求)。
· 技术平台、中间件、编程语言等的流行度、认同度、优缺点
等。
· 技术发展的趋势如何?
·……
架构师应当直接或间接(通过需求分析员)地了解和掌握上述需
求和约束,并深刻理解它们对架构的影响,只有这样才能设计出合适
的软件架构。例如,如果客户是一家小型超市,软件和硬件采购的预
算都很有限,那么你就不宜采用依赖太多昂贵中间件的软件架构设计
方案。
5.4 从需求向设计转化的“密码”
不重视需求,设计必死。对需求的重视停留在口头,却不能体现
到设计中,设计也会死。
我们都知道,整个设计“过程”中的关键一环是从需求向设计的
“转化”或“过渡”。少了这一环,“重视需求”就是一句口号,需
求和设计就是“两层皮”,设计就沦为了“拍脑袋”。
怎么办?
建议每一个架构师,都要精通“功能、质量、约束影响架构的不
同原理”——这,是从需求向设计转化的“密码”。
5.4.1 “理性设计”还是“拍脑袋”开发设计人员都知道,需求决定架构。看了本章前述内容后我们
又知道,软件需求=功能+质量+约束(如图5-14所示)。
图5-14 软件需求的类型
功能、质量、约束这三种需求影响架构的不同原理,是从需求向
设计的“转化的密码”和“过渡的钥匙”。要进行“理性设计”,这
是基础。表 5-5 归纳了不同需求如何以不同原理影响架构设计的。
表5-5 不同需求影响架构的原理不同5.4.2 功能:职责协作链
任何一项功能都是由一条特定的“职责协作链”完成的,如图 5-
15 所示。作为完整的软件系统,它在支持每一个具体功能时,都必然
涉及软件不同“部分”之间的相互配合。系统的控制权在这些不同的
“部分”之间来回传递,形成一条“职责协作链”,可以完成非常复
杂的功能。图5-15 功能影响架构的基本原理:职责协作链
反过来,在设计架构时,就是要通过为功能规划职责协作链来发
现职责,再将职责分配到子系统等软件单元中去,后续就可以定义接
口,确定协作方式了……
5.4.3 质量:完善驱动力
质量,是完善架构设计的驱动力,不考虑质量的系统是无法走出
实验室的。如图 5-16 所示,基于中间设计成果进一步质疑是其中基
本的“思维方式”。例如,如果只考虑功能,“页面缓存”的设计就
永远不会被引入,它是质疑性能、调整设计的结果。图5-16 质量影响架构的基本原理:进一步质疑
必须注意:
第一,抛开功能、单依据质量要求,是不可能设计出架构的。打
个赌:我有个 2000 万的系统想请你承接,不告诉你业务领域和功能
要求,你能设计出一个高性能的架构给我评审吗?
第二,实际的设计过程是,质量是一种评价、一种针对“已然存
在”的设计的评价,我们基于当前的架构设计中间成果,进一步考虑
具体质量要求,对设计中间成果进行细化、调整、甚至推倒重来……
5.4.4 约束:设计并不自由
设计并不自由。对于架构设计而言,来自方方面面的约束性需求
中潜藏了大量风险因素。所以,有经验的架构师都懂得主动分析约束影响、识别架构影响因素,以便在架构设计中引入相应决策予以应
对。
我们以 ADMEMS 矩阵为“思维画布”,考虑一个银行储蓄系统可
能涉及的约束需求(如图5-17所示),是如何以不同的具体方式影响
架构设计的:
· 直接制约设计决策的约束 。例如,“系统运行于 UNIX 平台
之上”作为一条约束,架构师直接遵守即可。
· 转化为功能需求的约束 。例如,“本银行系统必须严格执行
人民银行统一规定的利率”是一条约束,但分析后发现,正是它引出
了一条功能需求,即必须提供调整利率设置的实用功能。
· 转化为质量属性需求的约束 。例如,有经验的系统分析员发
现了一条重要约束:“任职于各储蓄所和分理处的柜员,计算机水平
普遍不高”。由此,未来的软件系统必须具有很高的易用性(否则不
会用)和鲁棒性(否则可能把系统搞瘫痪了)就是非常必要的。
图5-17 分析约束影响示例(银行储蓄系统)
5.5 实际应用(3)——PM Suite贯穿案例之需求分析
知识点、技能项都讲了不少,下面实际应用到PM Suite 贯穿案
例,对PM Suite 系统进行需求分析。需求分析主线中所包含的关键步骤,可以概括为“三横两纵”,如图5-18所示。
· 三横。
确定系统目标。
研究高层需求。
建立用例模型。
· 两纵。
需求沟通、需求启发、需求验证。
确定非功能需求。
所谓“纵”,指的是实践中需要持续不断地进行。所谓“横”,则是有先后之分的。“确定系统目标→研究高层需求→建立用例模
型”这三步,后一步需要前一步的工作成果作为输入,如图5-19所
示。
图5-18 需求分析主线的“三横两纵”图5-19 需求分析主线的“三横”
5.5.1 PM Suite案例背景介绍
PM S uite,是一个分布式的组织级项目管理系统,是本书用做贯
穿案例的一个虚拟的软件产品。
PM Suite覆盖企业的单项目管理、项目群、项目组合管理,以及
配套的辅助管理。它包含丰富的功能,涉及决策层、管理层、实施层
等众多功能点,帮助组织统管项目实施层、管理层、决策层,有助于
企业固化项目管理流程和体系。
PM Suite 互操作性强,能与其他不同知名产品(例如配置管理、Bug管理)整合,从而将组织项目管理体系连成一个整体,改善项目管
理的效能。
5.5.2 第1步:明确系统目标一个客户组织,为什么要采购PM Suite作为项目管理平台呢?
PM Suite 作为一个软件产品要被开发,要拨款立项,我们首先要
搞清楚一个问题——即确定系统的建设目标。经过了解情况,梳理分
析,我们确定了 PM Suite 要达到的四大业务目标(如表5-6所示)。
表5-6 整个PM Suite贯穿案例的第1 个工作成果
PM Suite 产品的“根”就在这里:系统的业务目标。我们要把业
务目标写入《愿景文档》,成为《愿景文档》内容的关键部分。若是
采用敏捷软件开发方式,也必须重视业务目标,可以采用“目标列
表”的形式明确记录它。
5.5.3 第2步:范围+Feature+上下文图
现在,我们已经明确了 PM Suite 的 4 个业务目标。接下来,是
不是就可以进行用例建模了呢?
如果是小系统,接下来就可以用例建模了;但如果是大系统,或
是业务复杂的系统,或是解决方案,明智的做法是
在确定业务目标之后、进行用例建模之前,通过“范围
+Feature+上下文图”来进一步明确高层需求。
【技能1】高层需求之确定范围
实际工作当中,描述需求范围经常采用的方式有如下几种:1)文
字描述法;2)业务域列举法;3)框图法(平实风格);4)框图法
(商务风格)。对于 PM Suit e 系统,我们经由对“组织级项目管理”涉及管理
内容的分析,确定它的需求范围(Scope)涵盖4块主要内容。如果采
用“业务域列举”法,可以这样描述:
· 项目基础管理。
· 单项目管理。
· 项目群管理。
· 项目组合管理。
如果换用“框图法(平实风格)”,可以用图5-20来进行描述。
图5-20 PM Suite高层需求之需求范围
如果你是为公司写市场材料,画图当然要更“炫”一些,此时
“框图法(商务风格)”是不二之选。例如,图 5-21 就采用了商务
风格的框图法,该图来自维普公司(http:www.vpsoft.cn)的市场
材料,描述的就是相关产品的“需求范围”。图5-21 采用“框图法(商务风格)”描述需求范围
(图片来源:http:www.vpsoft.cn)
【解惑】需求范围框图 ≠ 架构图
在笔者为不少企业提供架构培训的课堂间隙,都有学员提出类似
“需求范围框图是不是架构图”的问题。最典型的是有一次,一位学
员拿着一个软件厂商的市场彩页给我看,说:“温老师,你看这个材
料,上面可是把这个图叫‘架构图’的呀……”
其实这样的图(如图 5-22 所示),最精确的叫法就是“需求范
围框图”,这才是揭示此图本质的称呼。图5-22 “需求范围框图”的例子
【技能2】高层需求之定义Feature
Feature的应用,在实际工作中比较灵活,但也有规律。归纳而
言:
· 内容。
列举系统大致支持哪些功能组(粒度:大)。
例如:办公软件“公文交换”Feature,其实是功能组。
强调说明某些最有特色的功能项(粒度:中)。
例如:办公软件“支持公文下发、上报和水平发送等多种方式”
Feature,其实是列举功能项。
点出功能项的更细节优势(粒度:小)。
例如:办公软件“在 Word 中编辑的公文可直接在 Word 中发起
上报,快捷高效”Feature,其实是说明一个功能项(公文上报)的具
体卖点。
技术特色、其他特色的强调。
例如:办公软件“和微软 Office、即时通信软件无缝整合”及
“多浏览器支持”等Feature,就是在讲技术特色。· 描述方式。
文字描述法。
框图法。
功能树法。
现在,我们继续PM Suite 贯穿案例的需求分析。既然前面已明确
了“需求范围”,下面我们问自己:在此“需求范围”内为了达到
“业务目标”需要具有哪些Feature才行呢?
图5-23展示了PM Suite 案例的从业务目标到特性列表的思维过
程。例如,为了实现“统一平台”的目标,一方面要“内置著名软件
工具的集成支持”,另一方面要“方便通过二次开发集成新的工
具”,看来将来对Web S ervice或著名消息中间件等技术的支持在所
难免。再例如,为了实现提高“组织级项目管控力”的目标,“覆盖
和打通组织级与项目级项目管理”这一Feature就必不可少。图5-23 PM Suite:从业务目标到特性列表
基于此思维过程的启发,我们可以分析出 PM Suite 系统应具有
的 Feature,采用“文字描述法”描述如下。
· 功能覆盖4大业务域:单项目管理、项目群管理、项目组合管
理、基础管理。
(说明:显然,此项Feature重复了“需求范围”)
· 单项目管理相关的功能组包括:任务管理、进度管理、范围管
理、……
· 项目群管理相关的功能组包括:项目关联管理、生命周期管
理、……
· 项目组合管理的功能组包括:项目组合分析、项目组合监控、……· “生命周期管理”功能的如下具体特色非常有竞争力:内置
PMBOK、CMMI、GJB 等规范的管理过程模板,通过方便设置即可生效。
· 技术特色:与著名工具的无缝集成。
· 技术特色:二次开发支持。
同样,基于市场宣传的需要,“你”可以将Feature以美化的形式
展示出来,凸显产品特色和卖点。例如图 5-24 和图 5-25,分别来自
北京维普时代和 IBM,用于分别描述这两家公司推出的项目管理产品
的关键Feature。
图5-24 将Feature用于市场材料的例子(图片来源:北京维普时代)图5-25 将Feature用于市场材料的例子(图片来源:lBM)
嗯,的确如此,任凭市场彩页再怎么多“彩”,核心内容必少不
了如下“两高”:
· 一是诸如功能范围、Feature等这些需求分析的“高层成
果”。
· 二是诸如高层架构、技术优势等这些设计的“高层成果”。……如果读者您是开发人员,在看到我们贯穿案例的需求分析环
节和“市场宣传”也能挂起钩来,是否感到吃惊?程序员必须知道,向架构师转型时,必须深刻领会“技术和市场并不是孤立的”。转,既意味着岗位职责的转变,又意味着技术技能的转换,还意味着思维
焦点的转移。
【解惑】
整体来看,Feature(特性)在实践中其实有两种大相径庭的用
法:
· 一种是把 Feature 看做从业务目标向具体需求过渡的手段,它的数量将比具体的用户需求的数量要少一个数量级。这时,Feature
以“高度概括的功能组+少数重要功能项+少数功能实现特色+少数技术
特点”为内容。· 另外一些实践者把特性当做比“功能”更小的需求单位,例如
特性驱动开发(Feature Driven Develo pment,FDD)方法就持这种
观点。实践起来,Feature 的数量将大大多于“功能项”的数量。
本书认为,Feature 的第一种用法对实践非常有帮助。Feature
作为从业务目标向具体需求的过渡手段,启发了未来系统应在大方向
上具有哪些方面的特性(后续可以把每个特性落实到一个或一组功能
中),以一种实实在在的方式加强了需求分析师的系统化思维。
【技能3】高层需求之画上下文图
现在,该画PM Suite的上下文图了。
由于上下文图描述的本系统、相关系统、外部因素、信息流等要
素很大程度上就是在“刻画现实”,因此上下文图是高层需求三剑客
(范围、Feature、上下文图)中“实感性”最高的一个。上下文图画
法,常用的有三种:
· 顶层数据流图。
· 将System处理成黑盒的用例图。
· Powerpoint等绘制的框图。
如图5-26所示,我们采用“顶层数据流图”画法,绘制了PM
Suite的上下文图。
5.5.4 第3步:画用例图
好了,现在我们不仅确定了 PM Suite 的业务目标(4 点目
标),还将目标落实到了“面”状范围(4块内容)、“点”状
Feature(N个特性)、上下文图(系统边界)。
用例建模时,上述成果能起到很大的启发作用:
· 系统外部——用例图的Actor有哪些呢?首先“上下文图”的
外部实体会给你启发。
· 系统内部——用例图的 Use Case 要充分覆盖“范围”的规
定,并体现“Feature”的要求。图5-26 PM Suite:上下文图
例如,根据 PM Suite“组织级项目管理平台”这一定位和需求范
围“基础管理+单项目管理+项目群管理+项目组合管理”这4大业务
域,不难分析出PM Suite的5种用户角色:
· 项目成员。
· 项目经理。
· 部门经理高层。
· 过程经理。
· 系统管理员。
再加上上下文图中明确的和PM Suite 有交互的5个外部系统,用
例图中的10种Actor就确定下来了。如图5-27所示。图5-27 用例图绘制过程:确定System的Actor
再继续,不断明确每个 Actor 相关联的每种用例(具体功能
项),绘制用例图。既然系统较大,就采用多幅用例图的方式:
· 如图5-28所示,该用例图描述了与“系统管理员”和“过程经
理”相关的所有用例。
· 如图5-29所示,“单项目管理”业务域的用例被展现到用例图
中。
·……图5-28 用例图绘制过程:明确部分用例图5-29 用例图绘制过程:明确部分用例
当然,“用例图+用例简述”经常一起出现、配合使用,在此不再
赘述。
5.5.5 第4步:写用例规约
上面,我们梳理了用户需求。所谓用户需求,就是用户希望软件
系统能为他做什么。用例图技术是捕获和记录用户需求的合适技术,1)它清晰地将系统的用户、外部协作系统建模成Actor,2)“以用户
(和外部系统)为中心”梳理系统应当具有的能力,3)将这些能力建
模成用例,为用例命名以最直观地体现用户需求。
接下来,就是写用例规约了。
用例图并不足够。换句话说,需求分析进行到用户需求的层次并
不足够,因为如果不明确定义软件系统的行为需求,我们就不知道要
开发什么。基于用例技术的需求实践中,此时应和用户一起编写用例
规约(对于简单并不易产生歧义的需求可以仅通过“用例简述”说
明)。
仅举一例,如表5-7所示为“添加项目任务”的用例规约。
表5-7 用例:添加项目任务5.5.6 插曲:需求启发与需求验证
在需求分析过程中需要不断地和客户进行交流,这时客户非常希
望能够看到给他带来实际感受的界面草图甚至可执行的系统原型。而
开发方最担心的问题是客户需求的不断变化,所以他们也希望能够尽
早掌握客户的真正需求,并希望需求成果得到客户的确认。为此,我们可以在需求分析期间就开始界面设计(如图 5-30 所
示),并将界面草图等设计成果用于和客户的交流当中,这样可以增
加实感、方便交流,并帮助客户“发现”他真正想要的功能。当然,界面设计的成果一般并不推荐放入《需求文档》,因为它们是设计而
不是需求。
举个例子。在一开始和讨论“添加项目任务”这项需求时,我们
和用户可能都没有意识到两个需求细节:
· 用户希望能为每项任务指定优先级,这样有利于承担多项任务
的项目成员在时间不够时权衡取舍;
· 出于对易用性的极高要求,用户要求确定任务细节的时机必须
非常灵活。
图5-30 界面设计与需求分析
后来,在界面图和可执行原型的帮助下,用户能比较容易地意识
到“令人不满的地方到底在哪儿”,明确提出了上面的“两个需求细
节”,开发方也更新了“添加项目任务”的界面原型。图5-31 展示了
更新后的界面原型:用户既可以只输入任务名称和所属项目就创建任
务,也可以同时指定许多详细信息。图5-31 利用原型启发需求和确认需求
5.5.7 插曲:非功能需求
非功能需求的满足程度对软件项目的成功非常关键,因此需求分
析中必须重视。
一部分非功能需求来自用户。诸如性能、易用性等软件质量属
性,虽然不像功能需求那样直接帮助用户达到特定目标,但并不意味
着软件质量属性不是必需的——恰恰相反,质量属性差的软件系统大
多都不会成功。
还有一部分非功能需求来自开发者和升级维护人员。软件的可扩
展性、可重用性、可移植性、易理解性和易测试性等非功能需求,都
属于“软件开发期质量属性”之列,它们都将影响开发和维护成本。
也有一部分非功能需求来自客户组织。架构师必须充分考虑客户
对上线时间的要求、预算限制,以及集成需要等非功能需求,还要特别关注客户所在领域的业务规则和业务限制。
因此,在实际需求分析工作中,非功能需求的确定很难一蹴而
就,应该时时关心、不断完善。在表5-8中,着重列举了PM Suite的非
功能需求。
表5-8 PM Suite的非功能需求
5.5.8 《需求规格》与基于ADMEMS矩阵的需求评审
后续的需求文档编写和需求评审也很重要,在此不再详述。
《软件需求规格说明书(SRS)》是需求分析工作最重要的成果,本书第 6 章会说明采用用例建模技术时编写《软件需求规格说明书》
的几点注意。
任何一个有经验的设计者都不想“无论 SRS 好坏,唯 SRS 是
瞻”,这就需要需求评审的能力。基于本章讲过的ADMEMS 矩阵(需求
层次—需求方面矩阵)用来检查需求是否全面、是否有遗漏,是一种
务实有效的办法。第6章 用例与需求
需求=功能+质量+约束。用例是功能需求实际上的标准。用例涉
及、但不涵盖非功能需求。
——温昱,《一线架构师实践指南》
仅在需求规格中出现用例图并不意味着应用了用例技术。
——徐锋,《软件需求最佳实践》
几年来,笔者接触了大量开发人员,发现只要是关心设计的开发
人员,都关心用例技术,认为用例技术很流行、很有用,希望更好地
掌握这种技术。
本章立足软件开发人员的视角,抽取一些实际问题,并在最后的
“实际应用”一节解决“用例建模够不够?流程建模要不要?”的常
见困惑,希望对更清晰地运用用例技术有所帮助:
· 用例图、用例规约、用户故事,这些技术有什么关系?
· 如何应用?
· 需求分析的三套实践论中,用例建模和流程建模的关系是什
么?
6.1 用例技术族
用例技术是多种技术组成的“技术族”,不应该一概而论,那种
把所有这些技术一股脑儿称为“用例模型”的做法,不利于学习,也
不利于实践。
本节借助银行的储蓄系统为背景案例,说明这些技术的不同:
· 用例图。
· 用例简述(用户故事)。
· 用例规约。
· 用例实现(鲁棒图)。
6.1.1 用例图用例图描述软件系统为用户或外部系统提供的服务。结合图6-1:
· 用例图最重要的元素是参与者(Actor)和用例(Use Ca
se),以此体现系统能为外部参与者(Actor)提供的功能(Use
Case);
· 参与者是与系统交互的角色或系统,既可以是系统的用户
(User),也可以是和系统有直接交互关系的系统(System);
· 用例的名称应该从参与者的角度进行描述,并以动词开头,这
样一来通过“读图”可以清晰地获得用例图的语义,例如图 6-1 中
“连读”出“柜员开户”、“柜员销户”等语义。
图6-1 储蓄系统用例图的一部分
可见,用例图所做的,一是确定与本系统交互的角色或外部系
统,二是描述系统必须提供的功能。对系统研发而言,用例图以可视
化的方式进一步明确了系统功能范围(Scope)内的所有功能。
6.1.2 用例简述、用户故事
用例图中所含的用例必须被命名,但用例图中所含的用例信息也
仅此而已了。因此,还需要其他的“用例说明技术”对用例进行更进
一步的说明。
用例简述就是“用例说明技术”中最简单、最实用的一种。所谓
用例简述,就是通过简短的文字对用例的功能进行描述;一般而言,用例简述都应包含成功场景的简单描述。如表 6-1 所示,它对储蓄系
统“销户”用例进行了简要描述。
表6-1 储蓄系统“销户”用例简述
很多敏捷方法都通过类似用例简述的技术捕获和交流需求,例如
极限编程(eXtreme Programming,XP)的 ......
本书围绕“软件架构设计”主题,从“程序员”成长的视角,深
入浅出地讲述了架构师的修炼之道。从“基础篇”、到“设计过程
篇”、到“模块划分专题”,本书覆盖了架构设计的关键技能项,并
且对于架构设计过程中可能出现的各种问题给与了解答。
本书对于有志于成为架构师的程序员们具有非常有效的指导意
义,对于已经成为架构师的同行们系统化规范架构设计也是一本很好
的教材。
未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。
版权所有,侵权必究。
图书在版编目(ClP)数据
软件架构设计:程序员向架构师转型必备温昱著.—2版.—北
京:电子工业出版社,2012.7
ISBN 978-7-121-17087-4
Ⅰ.①软… Ⅱ.①温… Ⅲ.①软件设计-教材 Ⅳ.①TP311.5
中国版本图书馆CIP数据核字(2012)第101071号
责任编辑:孙学瑛
印刷:
装订:
北京中新伟业印刷有限公司
出版发行:电子工业出版社
北京市海淀区万寿路173信箱 邮编100036
开本:787×1092 116 印张:16.5 字数:341千字印次:2012年7月第1次印刷
印数:5000册 定价:39.00元
凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。
若书店售缺,请与本社发行部联系,联系及邮购电话:(010)
88254888。
质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件
至dbqq@phei.com.cn。
服务热线:(010)88258888。Experts Recommend 专家推荐
(以姓氏笔划为序)
与温昱先生初识于一次部门内训,金融机构应用信息技术日久,但业务发展之快仍需信息技术部门不断思索如何提供有力的技术支
持,当时系统设计人员思路难成一致,故邀请先生来讲述所得,先生
讲座生动有趣,案例均为实践中心得,有助于一线设计人员在低头干
事之余,能够抬头看路,从架构高度理解和看待日常工作,《软件架
构设计(第 2 版)》同样着眼于研发实践,不作黄钟大吕之音,而以
一觞一咏畅叙分享一线设计师的感悟体会。此书值得一看,作者亦值
得一晤!
——朱晓光 中国建设银行 北京开发中心 处长
在厦门,曾和温老师有过4天晚上的坐而论道,从技术到业界、从
数据模型到软件重构、从职业观到心理学,彼此颇多启发。第一时间
收到本书的电子版,读来流畅易懂,胜似面晤对谈。本书内容务实、技能梳理清晰,实乃软件开发者职业生涯发展的重要参考。
——朱志 中国建设银行 厦门开发中心总工办
基于软件架构的开发模式,作为软件开发的最佳实践之一,越来
越得到各行各业的重视和关注,但遗憾的是理解其精髓和内涵的人太
少。温老师作为软件架构思想的传播者和推动者,在这本书中,对程
序员如何成长为优秀的架构师给出了非常具体的指导原则和实现方
法,是国内不可多得的真正将软件架构思想阐述如此精准的实践指导
书。作为一名软件行业的从业者,我强烈推荐给大家。
——李哲洙 博士 东软集团 电信事业部 网管产品与系统部部长
这本书以架构设计人员实际工作流程为线索,详细阐述了逻辑架
构和物理架构视图的重要性及其在架构设计中的应用方法。此外,本
书从实践的角度,给出了架构设计的三个原则和 6 大步骤,并以具体
实践过程为指导,给出了架构设计从需求分析到最后的架构设计、架
构验证的完整的架构设计生命周期的实践方法,对软件研发项目团队
和架构师的研发实践工作具有很好的指导意义。——杨勇 中兴通讯 业务研究院 平台总工
从事软件工作近十年,由软件功能模块的程序员开始,到独立负
责几个软件项目的设计开发,一直对软件架构设计比较关注,有幸听
了温昱老师的“软件架构设计”讲座,顿感茅塞顿开,再次阅读温老
师的《软件架构设计》,对架构设计有了更深的感悟。如果你对软件
架构设计感觉朦朦胧胧,温先生的《软件架构设计(第2版)》定能让
你拨开云雾见青天。
——杨为禄 南京国睿安泰信科技股份有限公司 一线软件工程师
近年来,阅读了诸多系统、需求、架构类的书籍资料,温老师的
几本书简明扼要,见解独到,颇多启发。“横看成岭侧成峰,远近高
低各不同”,大系统架构(体系结构)包括系统组分、组分间的关
系,以及演化等三要素;温老师在本书中给出了典型视角、典型模
式、典型过程等实践指南。有志创造系统,赋予软件灵魂的架构师,当读此书。
——张雪松 中国电子科学研究院 复杂大系统研究与仿真
架构是很玄的东西,成为优秀的架构师也是大部分程序员的理
想。温昱先生这本书的特点就是从程序员角度,深入浅出地讲述了架
构师的修炼之道。程序员与架构师区别的最重要一点是看待事物的角
度和处理方法,优秀的程序员按照本书的方法,在日常工作中一步步
实践,有助于培养出架构师的能力,从而逐步成长成为架构师。架构
的目标是为了沟通和交流,温先生也深刻地领悟到这一架构设计的根
本目标,并将这一目标转化为方法论。架构设计不是给自己看的,而
是为了与客户、领导和团队沟通,本书的重点在于架构设计实践,从
用例、需求分析、概念模型、细化模型等一步步地指导如何完成架构
设计,并且对于架构设计过程中可能出现的各种问题给予了解答。本
书对于有志于成为架构师的程序员们具有非常有效的指导意义,对于
已经成为架构师的同行们系统化规范架构设计也是一本很好的教材。
——钱煜明 中兴通讯 业务研究院 移动互联网总工程师
早在2009年的时候就读过温老师的《软件架构设计》第一版,2011年有幸请到温老师来公司主讲“软件架构设计”,幸有当面请教的机会,温老师对软件架构独特的授课方法和深厚的功底让我如沐春
风、豁然开朗,颇有几分“顿悟”之感。
五年磨一剑,如今有幸抢先拜读温老师的《软件架构设计》第二
版,更是被书中内容所折服。书中融合了作者多年来在一线的实践和
培训经验,深入浅出地阐释了什么是软件架构,手把手教你从客户需
求入手顺畅地设计出高可用的软件架构,让你读完本书后情不自禁地
感叹:“原来软件架构设计并没有那么高深莫测!”该书理论和实践
并重,是一本不可多得的软件架构设计的指导书籍。
——崔朝辉 东软集团 技术战略与发展部 资深顾问
站得足够高,才能看得足够远。当今 IT 的架构设计思想理念已
经是经过数次洗礼之后的结晶,而温昱先生抓住了这一结晶生命体的
真正骨架,并深入浅出地汇集成这本书。有了这本书,你就可以依据
自己的Project来高效地添加血肉,构建出独特的有机生命体。
——谌晏生 广州从兴 电力事业部 一线软件设计师作者介绍
温昱 资深咨询顾问,软件架构专家。软件架构思想的传播者和积
极推动者,中国软件技术大会杰出贡献专家。十五年系统规划、架构
设计和研发管理经验,在金融、航空、多媒体、电信、中间件平台等
领域负责和参与多个大型系统的规划、设计、开发与管理。
wy@yupeisoft.com
昱培咨询专注于如下三个领域的咨询与培训:
■ 架构设计
■ 详细设计
training@yupeisoft.com
■ 设计重构
几年来,我们为近百家软企提供了卓有成效的服务。
长期一线经验的积累,更促成了 ADMEMS 架构实践体系、ARCT 设
计重构方法论的形成和成熟,并已成为了我们服务品质的重要保证之
一。目录
Experts Recommend 专家推荐
作者介绍
第1章 从程序员到架构师
1.1 软件业人才结构
1.1.1 金字塔型,还是橄榄型?
1.1.2 从程序员向架构师转型
1.2 本书价值
1.2.1 阅读路径1:架构设计入门
1.2.2 阅读路径2:领会大系统架构设计
1.2.3 阅读路径3:从需求到架构的全过程
1.2.4 阅读路径4:结合工作,解决实际问题
第1部分 基本概念篇
第2章 解析软件架构概念
2.1 软件架构概念的分类
2.1.1 组成派
2.1.2 决策派
2.1.3 软件架构概念大观
2.2 概念思想的解析
2.2.1 软件架构关注分割与交互
2.2.2 软件架构是一系列有层次的决策
2.2.3 系统、子系统、框架都可以有架构
2.3 实际应用(1)——团队对架构看法不一怎么办
2.3.1 结合手上的实际工作来理解架构的含义
2.3.2 这样理解“架构”对吗2.3.3 工作中找答案:先看部分设计
2.3.4 工作中找答案:反观架构概念的体现
第3章 理解架构设计视图
3.1 软件架构为谁而设计
3.1.1 为用户而设计
3.1.2 为客户而设计
3.1.3 为开发人员而设计
3.1.4 为管理人员而设计
3.1.5 总结
3.2 理解架构设计视图
3.2.1 架构视图
3.2.2 一个直观的例子
3.2.3 多组涉众,多个视图
3.3 运用“逻辑视图+物理视图”设计架构
3.3.1 逻辑架构
3.3.2 物理架构
3.3.3 从“逻辑架构+物理架构”到设计实现
3.4 实际应用(2)——开发人员如何快速成长
3.4.1 开发人员应该多尝试设计
3.4.2 实验项目:案例背景、训练目标
3.4.3 逻辑架构设计(迭代1)
3.4.4 物理架构设计(迭代1)
3.4.5 逻辑架构设计(迭代2)
3.4.6 物理架构设计(迭代2)
第2部分 实践过程篇
第4章 架构设计过程
4.1 架构设计的实践脉络
4.1.1 洞察节奏:3个原则4.1.2 掌握过程:6个步骤
4.2 架构设计的速查手册
4.2.1 需求分析
4.2.2 领域建模
4.2.3 确定关键需求
4.2.4 概念架构设计
4.2.5 细化架构设计
4.2.6 架构验证
第5章 需求分析
5.1 需求开发(上)——愿景分析
5.1.1 从概念化阶段说起
5.1.2 愿景
5.1.3 上下文图
5.1.4 愿景分析实践要领
5.2 需求开发(下)——需求分析
5.2.1 需求捕获vs.需求分析vs.系统分析
5.2.2 需求捕获及成果
5.2.3 需求分析及成果
5.2.4 系统分析及成果
5.3 掌握的需求全不全
5.3.1 二维需求观与ADMEMS矩阵
5.3.2 功能
5.3.3 质量
5.3.4 约束
5.4 从需求向设计转化的“密码”
5.4.2 功能:职责协作链
5.4.3 质量:完善驱动力
5.4.4 约束:设计并不自由5.5 实际应用(3)——PM Suite贯穿案例之需求分析
5.5.1 PM Suite案例背景介绍
5.5.2 第1步:明确系统目标
5.5.3 第2步:范围+Feature+上下文图
5.5.4 第3步:画用例图
5.5.5 第4步:写用例规约
5.5.6 插曲:需求启发与需求验证
5.5.7 插曲:非功能需求
5.5.8 《需求规格》与基于ADMEMS矩阵的需求评审
第6章 用例与需求
6.1 用例技术族
6.1.1 用例图
6.1.2 用例简述、用户故事
6.1.3 用例规约
6.1.4 用例实现、鲁棒图
6.1.5 4种技术的关系
6.2 用例技术族的应用场景
6.2.1 用例与需求分析
6.2.2 用例与需求文档
6.2.3 用例与需求变更
6.3 实际应用(4)——用例建模够不够?流程建模要不
要
6.3.1 软件事业部的故事
6.3.2 小型方法:需求分析的三套实践论(上)
6.3.3 中型方法:需求分析的三套实践论(中)
6.3.4 大型方法:需求分析的三套实践论(下)
6.3.5 PM Suite应用一幕
第7章 领域建模7.1 什么是领域模型
7.1.1 领域模型“是什么”
7.1.2 领域模型“什么样”
7.1.3 领域模型“为什么”
7.2 需求人员视角——促进用户沟通、解决分析瘫痪
7.2.1 领域建模与需求分析的关系
7.2.2 沟通不足
7.2.3 分析瘫痪
7.2.4 案例:多步领域建模,熟悉陌生领域
7.3 开发人员视角——破解“领域知识不足”死结
7.3.1 领域模型作为“理解领域的手段”
7.3.2 案例:从词汇表到领域模型
7.4 实际应用(5)——功能决定如何建模,模型决定功
能扩展
7.4.1 案例:模型决定功能扩展
7.4.2 实践:功能决定如何建模
7.4.3 PM Suite领域建模实录(1)——类图
7.4.4 PM Suite领域建模实录(2)——状态图
7.4.5 PM Suite领域建模实录(3)——可扩展性
第8章 确定关键需求
8.1 众说纷纭——什么决定了架构
8.1.1 用例驱动论
8.1.2 质量决定论
8.1.3 经验决定论
8.2 真知灼见——关键需求决定架构
8.2.1 “目标错误”比“遗漏需求”更糟糕
8.2.2 关键需求决定架构,其余需求验证架构
8.3 付诸行动——如何确定关键需求8.3.1 确定关键质量
8.3.2 确定关键功能
8.4 实际应用(6)——小系统与大系统的架构分水岭
8.4.1 架构师的“拿来主义”困惑
8.4.2 场景1:小型PMIS(项目型ISV背景)
8.4.3 场景2:大型PM Suite(产品型ISV背景)
8.4.4 场景3:多个自主产品组成的方案(例如
IBM)
8.4.5 “拿来主义”虽好,但要合适才行
第9章 概念架构设计
9.1 概念架构是什么
9.1.1 概念架构是直指目标的设计思想、重大选择
9.1.2 案例1:汽车电子AUTOSAR——跨平台复用
9.1.3 案例2:腾讯QQvideo架构——高性能
9.1.4 案例3:微软MFC架构——简化开发
9.1.5 总结
9.2 概念架构设计概述
9.2.1 “关键需求”进,“概念架构”出
9.2.2 概念架构≠理想化架构
9.2.3 概念架构≠细化架构
9.3 左手功能——概念架构设计(上)
9.3.1 什么样的鸿沟,架什么样的桥
9.3.2 鲁棒图“是什么”
9.3.3 鲁棒图“画什么”
9.3.4 鲁棒图“怎么画”
9.4 右手质量——概念架构设计(下)
9.4.1 再谈什么样的鸿沟,架什么样的桥
9.4.2 场景思维9.4.3 场景思维的工具
9.4.4 目标—场景—决策表应用举例
9.5 概念架构设计实践要领
9.5.1 要领1:功能需求与质量需求并重
9.5.2 要领2:概念架构设计的1个决定、4个选择
9.5.3 要领3:备选设计
9.6 实际应用(7)——PM Suite贯穿案例之概念架构设
计
9.6.1 第1步:通过初步设计,探索架构风格和高层
分割
9.6.2 第2步:选择架构风格,划分顶级子系统
9.6.3 第3步:开发技术、集成技术与二次开发技术
的选型
9.6.4 第4步:评审3个备选架构,敲定概念架构方
案
第10章 细化架构设计
10.1 从2视图方法到5视图方法
10.1.1 回顾:2视图方法
10.1.2 进阶:5视图方法
10.2 程序员向架构师转型的关键突破——学会系统思考
10.2.1 系统思考之“从需求到设计”
10.2.2 系统思考之“5个设计视图”
10.3 5视图方法实践——5个视图、15个设计任务
10.3.1 逻辑架构=模块划分+接口定义+领域模型
10.3.2 开发架构=技术选型+文件划分+编译关系
10.3.3 物理架构=硬件分布+软件部署+方案优化
10.3.4 运行架构=技术选型+控制流划分+同步关系
10.3.5 数据架构=技术选型+存储格式+数据分布10.4 实际应用(8)——PM Suite贯穿案例之细化架构
设计
10.4.1 PM Suite接下来的设计任务
10.4.2 客户端设计的相关说明
10.4.3 细化领域模型时应注意的两点
第11章 架构验证
11.1 原型技术
11.1.1 水平原型vs.垂直原型,抛弃原型vs.演进原
型
11.1.2 水平抛弃原型
11.1.3 水平演进原型
11.1.4 垂直抛弃原型
11.1.5 垂直演进原型
11.2 架构验证
11.2.1 原型法
11.2.2 框架法
11.2.3 测试运行期质量,评审开发期质量
第3部分 模块划分专题
第12章 粗粒度“功能模块”划分
12.1 功能树
12.1.1 什么是功能树
12.1.2 功能分解≠结构分解
12.2 借助功能树,划分粗粒度“功能模块”
12.2.1 核心原理:从“功能组”到“功能模块”
12.2.2 第1步:获得功能树
12.2.3 第2步:评审功能树
12.2.4 第3步:粗粒度“功能模块”划分12.3 实际应用(9)——对比MailProxy案例的4种模块
划分设计
12.3.1 设计
12.3.2 设计的优点、缺点
12.4 实际应用(10)——做总体,要提交啥样的“子系
统划分方案”
第13章 如何分层
13.1 分层架构
13.1.1 常见模式:展现层、业务层、数据层
13.1.2 案例一则
13.1.3 常见模式:UI层、SI层、PD层、DM层
13.1.4 案例一则
13.2 分层架构实践技巧
13.2.1 设计思想:分层架构的“封装外部交互”思
想
13.2.2 实践技巧:设计分层架构,从上下文图开始
13.3 实际应用(11)——对比MailProxy案例的4种模块
划分设计
13.3.1 设计
13.3.2 设计的优点、缺点
第14章 用例驱动的模块划分过程
14.1 描述需求的序列图vs.描述设计的序列图
14.1.1 描述“内外对话”vs.描述“内部协作”
14.1.2 《用例规约》这样描述“内外对话”
14.2 用例驱动的模块划分过程
14.2.1 核心原理:从用例到类,再到模块
14.2.2 第1步:实现用例需要哪些类
14.2.3 第2步:这些类应该划归哪些模块14.3 实际应用(12)——对比MailProxy案例的4种模块
划分设计
14.3.1 设计
14.3.2 设计的优点、缺点
第15章 模块划分的4步骤方法——运用层、模块、功能模
块、用例驱动
15.1 像专家一样思考
15.1.1 自顶向下vs.自底向上,垂直切分vs.水平切
分
15.1.2 横切竖割,并不矛盾
15.2 模块划分的4步骤方法——EDD方法
15.2.1 封装驱动设计的4个步骤
15.2.2 细粒度模块的划分技巧
15.3 实际应用(13)——对比MailProxy案例的4种模块
划分设计
15.3.1 设计
15.3.2 设计的优点、缺点第1章 从程序员到架构师
自由竞争越来越健全,真正拥有实力的人越来越受到推崇。……
努力钻研,力求在更高水平上解决问题的专家不断增加,这正如电脑
处理信息的能力在不断提高一般。如今,这样的时代正在到来。
——大前研一,《专业主义》
机会牵引人才,人才牵引技术,技术牵引产品,产品牵引更大的
机会。在这四种牵动力中,人才所掌握的知识处于最核心的地位。
——张利华,《华为研发》
人才,以及合理的人才结构,是软件公司乃至软件业发展的关
键。
成才,并在企业中承担重要职责,是个人职业发展的关键。
1.1 软件业人才结构
1.1.1 金字塔型,还是橄榄型?
有人说,软件业当前的人才结构是橄榄型(中间大两头小),需
求量最大的“软件蓝领”短缺问题最为凸显,这极大地制约着软件业
的发展,因此要花大力气培养大量的初级软件程序员等“蓝领工
人”。
但业内更多人认为,软件业当前的人才结构是金字塔型,高手和
专家型人才的总量不足才是“制约发展”的要害,因此一方面软件工
程师应争取提升技能、升级转型,另一方面企业和产业应加强高级技
能培训、高级人才培养。
软件业的人才结构,到底是金字塔型,还是橄榄型?
本书认为,一旦区分开“学历结构”和“能力结构”,问题就不
言自明了(如图1-1所示):
· 学历结构=橄榄型。“中级学历”最多。有资料称,软件从业
者中研究生、本科与专科的比例大致是1:7:2。· 能力结构=金字塔型。“初级人才”最多。工作 3 年以上的软
件工程师,就一跃成为“有经验的中级人才”了吗?显然不一定。
· 有学历 ≠ 有能力。每个开发者真正追求的是,成为软件业
“人才能力结构”的顶级人才或中级人才。
图1-1 人才结构的两个视角
1.1.2 从程序员向架构师转型
人才能力的金字塔结构,注定了软件产业的竞争从根本上是人才
的竞争。具体到软件企业而言,一个软企发展的好坏,极大地取决于
如下人才因素:
· 员工素质。
· 人才结构。
· 员工职业技能的纵深积累。
· 员工职业技能的适时更新。
借用《华为研发》一书中的说法,“机会、人才、技术和产品是
公司成长的主要牵动力。机会牵引人才,人才牵引技术,技术牵引产
品,产品牵引更大的机会。在这四种牵动力中,人才所掌握的知识处
于最核心的地位。”然而,纯粹靠从外部“招人”,不现实。何况,软件企业、软企
的竞争对手和软件产业环境,都处在动态发展之中。因此,软件企业
应该:
· 定期分析和掌握本公司的员工能力状况、人才结构状况;
· 员工专项技能的渐进提升(例如架构技能、设计重构技能);
· 研发骨干整体技能的跨越转型(例如高级工程师向架构师、系
统工程师和技术经理的转型)。
对于本书的主题“软件架构设计能力的提升”而言,架构设计能
力是实践性很强的一系列技能,从事过几年开发工作是掌握架构设计
各项技能的必要基础。因此可以说,“从程序员向架构师转型”不仅
是软件开发者个人发展的道路之一,也是企业获得设计人才的合适途
径。
1.2 本书价值
本书包含3部分,分别是:
· 第1部分:基础概念篇。
· 第2部分:实践过程篇。
· 第3部分:模块划分专题。
读者可以根据自身发展状况、实际工作需要,选择合适的阅读路
径(如图1-2所示)。图1-2 不同目的,不同阅读路径
1.2.1 阅读路径1:架构设计入门
对于架构还未入门的程序员,推荐先重点阅读“基础概念篇”和
“模块划分专题”:
· 基础概念篇解析架构概念(第 2 章)之后,讲解如何运用
“逻辑视图+物理视图”设计架构(第3章)。
· 模块划分专题讲解模块划分的不同方法,将讨论功能模块、分
层架构、用例驱动的模块划分过程等内容(第12~15章)。
架构设计入门必过“架构视图关”。本书细致讲解“逻辑视图+物
理视图”的运用,如图 1-3所示,体会了“分而治之”和“迭代式设
计”这两点关键思想,运用“逻辑视图+物理视图”设计一个系统的架
构也就不那么难了。
图1-3 两视图法的“分而治之”和“迭代”思想
架构设计入门必过“模块划分关”。本书“模块划分专题”总结
了模块划分的 4 种方式,如图 1-4 所示。这其中,既有“水平分
层”、“垂直划分功能模块”和“从用例到类、再到模块”等设计思
想,也有不推荐的想到哪“切”到哪的设计方式。图1-4 业界模块划分的4种做法
当一个程序员,看懂了他们团队的架构师是如何划分模块的(甚
至问“你为啥只垂直切子系统没分层呢”),那他离成为架构师还远
吗?
1.2.2 阅读路径2:领会大系统架构设计
入门之后,进一步学习大型系统架构成败的关键——概念架构设
计。推荐精读如下两章:
· 第8章。如何确定影响架构设计的关键需求。
· 第9章。概念架构如何设计。
小系统和大系统的架构设计之不同,首先是“概念架构”上的不
同,而归根溯源这是由于架构所支撑的“关键需求”不同造成的。整
个架构设计过程中的“确定关键需求”这一环节,可谓小系统和大系
统架构设计的“分水岭”,架构设计走向从此大不相同。
概念架构是直指系统目标的设计思想、重大选择,因而非常重
要。《方案建议书》《技术白皮书》和市场彩页中,都有它的身影,以说明产品项目方案的技术优势。因此,也有人称它为“市场架
构”。
概念架构设计什么?从设计任务上,概念架构要明确“1 个决
定、4个选型”,如图1-5所示。
图1-5 概念架构设计什么?
概念架构如何设计?从设计步骤的顺序上,本书推荐(如图1-6所
示):
· 首先,选择架构风格、划分顶级子系统。这两项设计任务是相
互影响、相辅相成的。
· 然后,开发技术选型、集成技术选型、二次开发技术选型。这
三项设计任务紧密相关、同时进行。另外可能不需要集成支持,也可
以决定不支持二次开发。图1-6 概念架构如何设计?
1.2.3 阅读路径3:从需求到架构的全过程
专业的架构设计师,必须掌握架构设计的“工程化过程”。以此
为目标的读者,请精读“实践过程篇”的内容。
· 第 4 章。概述从需求到架构的全过程,还提供了一节叫“速
查手册”,供快速查阅每个环节的工作内容。
· 第5~11章。按如下6 个环节的展开讨论:需求分析、领域建
模、确定关键需求、概念架构设计、细化架构设计、架构验证。
内容虽多,用一幅图概括也不是不可能,在为企业培训架构时我
们就经常这么做——图 1-7即,展示了从需求到架构整个过程中的关
键任务项。图1-7 架构设计的全过程
1.2.4 阅读路径4:结合工作,解决实际问题
最后,按照经典名著《如何阅读一本书》中所说的“主动阅读”
法,读者还可以“带着问题”、“以我为主”地“跳读”。
【实际问题1】 开发人员的一个很经典的困惑是:领域经验不足
怎么办?
本书第7章,给出了建议。破解“领域知识不足”死结的一个有效
方法,是把领域模型作为“理解领域的手段”。领域模型的“强项”
是“理顺概念关系、搞清业务规则”——通过对复杂的领域进行“概
念抽象”和“关系抽象”建立模型、获得对领域知识总体上的把握,就不会掉入杂乱无章的概念“堆”里了。
【实际问题 2】 又例如,你所在的部门,是否存在这样的问
题:不同的人对架构有不同的理解?
本书第2章,推荐结合部门的实际工作,来理解架构的含义,统一
团队不同成员对架构的理解。【实际问题3】 用例建模够不够?流程建模要不要?笔者接触的
很多实践者,都有此困惑。
本书第6章,简述了需求分析“三套实践论”的观点,提出“大、中、小”三套可根据系统特点选择的需求实践策略,可供实践者参
考。如图1-8、图1-9和图1-10所示。
图1-8 需求实践论之小型方法
图1-9 需求分析实践论之中型方法图1-10 需求实践论之大型方法
由此可见,是实践决定方法,不是方法一刀切实践。
更多问题的解决思路在此不再列举,祝阅读之旅愉快!第1部分 基本概念篇
第2章 解析软件架构概念
什么是架构?如果你问五个不同的人,可能会得到五种不同的答
案。
——lvar Jacobson,《AOSD中文版》
很多人都试图给“架构”下定义,而这些定义本身却很难统一。
——Martin Fowler,《企业应用架构模式》
不积跬步,无以至千里。
程序员在向架构师转型时,都希望尽早弄清楚“什么是架构”。
但是,架构的定义又多又乱,已造成“什么是架构”成了程序员向架
构师转型的“大门槛”。
本章,我们讨论软件架构的概念。
值得说明的是,人们对“Architecture”有着不同的中文叫法,比如架构、构架和体系结构等。本书将一贯地采用“架构”的叫法;
当然,当引用原文或提及书名时将保留原来的叫法。
2.1 软件架构概念的分类
一个词(比如“电脑”),可能并不代表一件单独的东西,而是
代表了一类事物。这个一般性的表述就是我们通常所说的“概念”。
也许读者期待一个干净利落的软件架构概念,但这有点儿难。对
此,Martin Fowler给出的评价是:
软件业的人乐于做这样的事——找一些词汇,并将它们引申到大
量微妙而又相互矛盾的含义中。一个最大的受害者就是“架构”这个
词。……很多人都试图给“架构”下定义,而这些定义本身却很难统
一。
本书将软件架构概念分为两大流派——组成派和决策派,帮助各
级开发人员快速理清“什么是架构”的基础问题。下面就采用这种方式介绍架构概念。
2.1.1 组成派
Mary Shaw 在《软件体系结构:一门初露端倪学科的展望》中,为“软件架构”给出了非常简明的定义:
软件系统的架构将系统描述为计算组件及组件之间的交互。(The
arc hitecture of a software system defines that system in
terms of computational components and interactions among
those components.)
必须说明,上述定义中的“组件”是广泛意义上的元素之意,并
不是指和 CORBA、DCOM、EJB 等相关的专有的组件概念。“计算组
件”也是泛指,其实计算组件可以进一步细分为处理组件、数据组
件 、 连 接 组 件 等 。 总 之 , “ 组 件 ” 可 以 指 子 系 统 、 框 架
(Framework)、模块、类等不同粒度的软件单元,它们可以担负不同
的计算职责。
上述定义是“组成派”软件架构概念的典型代表,有如下两个显
著特点:
(1)关注架构实践中的客体——软件,以软件本身为描述对象;
(2)分析了软件的组成,即软件由承担不同计算任务的组件组
成,这些组件通过相互交互完成更高层次的计算。
2.1.2 决策派
RUP(Rational Unified Process,Rational统一过程)给出的架
构的定义非常冗长,但其核心思想非常明确:软件架构是在一些重要
方面所做出的决策的集合。下面看看它的定义:
软件架构包含了关于以下问题的重要决策:
· 软件系统的组织;
· 选择组成系统的结构元素和它们之间的接口,以及当这些元素
相互协作时所体现的行为;
· 如何组合这些元素,使它们逐渐合成为更大的子系统;· 用于指导这个系统组织的架构风格:这些元素以及它们的接
口、协作和组合。
· 软件架构并不仅仅注重软件本身的结构和行为,还注重其他特
性:使用、功能性、性能、弹性、重用、可理解性、经济和技术的限
制及权衡,以及美学等。
该定义是“决策派”软件架构概念的典型代表,有如下两个显著
特点:
(1)关注架构实践中的主体——人,以人的决策为描述对象;
(2)归纳了架构决策的类型,指出架构决策不仅包括关于软件系
统的组织、元素、子系统和架构风格等几类决策,还包括关于众多非
功能需求的决策。
2.1.3 软件架构概念大观
下面再列举几个著名的软件架构定义,请大家:
· 结合实践,体会自己所认为的“架构”是什么,也可问问周围
同事对架构的理解;
· 体会专家们给“架构”下的定义虽多,但万变不离其宗——都
是围绕“组成”和“决策”两个角度定义架构的;
· 注意区分,下面的定义1和定义2属于架构概念的“决策派”,而定义3、4、5、6、7属于架构概念的“组成派”;
· 关注定义 7(来自 SEI 的 Len B ass 等人),它将架构的多
视图“本性”体现到了定义当中,是相对比较新的定义,业界都深表
认同。
1.Booch、Rumbaugh和Jacobson的定义
架构是一系列重要决策的集合,这些决策与以下内容有关:软件
的组织,构成系统的结构元素及其接口的选择,这些元素在相互协作
中明确表现出的行为,这些结构元素和行为元素进一步组合所构成的
更大规模的子系统,以及指导这一组织——包括这些元素及其接口、它们的协作和它们的组合——架构风格。
2.Woods的观点Eoin W oods 是这样认为的:软件架构是一系列设计决策,如果
做了不正确的决策,你的项目可能最终会被取消(Software
architecture is the set of de sign deci sions which,if made
incorrectly,may cause your project to be cancelled.)。
3.Garlan和Shaw的定义
Garlan 和 Shaw 认为:架构包括组件(Component)、连接件
(Connector)和约束(Constrain)三大要素。组件可以是一组代码
(例如程序模块),也可以是独立的程序(例如数据库服务器)。连
接件可以是过程调用、管道和消息等,用于表示组件之间的相互关
系。“约束”一般为组件连接时的条件。
4.Perry和Wolf的定义
Perry和Wolf提出:软件架构是一组具有特定形式的架构元素,这
些元素分为三类:负责完成数据加工的处理元素(Processing Ele
ments)、作为被加工信息的数据元素(Data Elem ents)及用于把架
构的不同部分组合在一起的连接元素(Connecting Elements)。
5.Boehm的定义
Barry Boeh m 和他的学生提出:软件架构包括系统组件、连接件
和约束的集合,反映不同涉众需求的集合,以及原理(Rationale)的
集合。其中的原理,用于说明由组件、连接件和约束所定义的系统在
实现时,是如何满足不同涉众需求的。
6.lEEE的定义
IEEE 610.12-1 990 软件工程标准词汇中是这样定义架构的:架
构是以组件、组件之间的关系、组件与环境之间的关系为内容的某一
系统的基本组织结构,以及指导上述内容设计与演化的原理
(Principle)。
7.Bass的定义
SEI(Software Engineering Institute,SEI,美国卡内基·梅
隆大学软件研究所)的 Len B ass等人给架构的定义是:某个软件或
计算机系统的软件架构是该系统的一个或多个结构,每个结构均由软
件元素、这些元素的外部可见属性、这些元素之间的关系组成。(The
softwa re architecture of a program or co mputing sy stem isthe struct ure or structures of the sy stem,which co mprise
softwar e elements , the externally visible properties of
those elements,and the relationships among them.)
2.2 概念思想的解析
2.2.1 软件架构关注分割与交互
架构设计是分与合的艺术。
“软件系统的架构将系统描述为计算组件及组件之间的交互”,Shaw 的这个定义从“软件组成”角度解析了软件架构的要素:组件及
组件之间的交互。如图2-1所示(采用UML类图),架构=组件+交互,组件和组件之间有交互关系(图中的“交互”关系建模成UML关联
类)。
下面以大家熟悉的MVC架构为例进行说明。如图2-2所示。
· 采用MVC架构的软件包含了这样3种组件:Model、View、Controller。
· 这 3 种组件通过交互来协作:View 创建 Controller 后,Controller 根据用户交互调用Model的相应服务,而Model会将自身的
改变通知View,View则会读取Model的信息以更新自身。
图2-1 软件架构的要素:组件及组件之间的交互图2-2 MVC架构作为“组件+交互”的例子
通过此例可以看出,“组件+交互”可以将 MVC 等“具体架构设
计决策”高屋建瓴地抽象地表达出来。
2.2.2 软件架构是一系列有层次的决策
架构属于设计,但并非所有设计都属于架构。架构涉及的决策,往往对整体质量、并行开发、适应变化等方面有着重大影响(否则就
放到详细设计环节了):
· 模块如何划分。
· 每个模块的职责为何。
· 每个模块的接口如何定义。
· 模块间采用何种交互机制。
· 开发技术如何选型。
· 如何满足约束和质量属性的需求。
· 如何适应可能发生的变化。……
还有很多
而且实际的设计往往是分层次依次展开的——无论是决策如何切
分系统还是决策技术选型都是如此:
· 例如,你设计一个 CS 系统时,是不是经历着这样一个“决
策树”过程:……嗯,我决定采用 CS 架构,系统包含 Client 和Server;……嗯,我决定将 Server 分为三层;……嗯,我决定将
Server的引擎层划分为N个模块;……(如图2-3所示。)
· 例如,你设计一个 BS 系统时,可曾有过这样的“决策过
程”:……嗯,我决定 BS前端采用JSP技术;……嗯,具体到
Framework我选Struts;……(如图2-4所示。)再举一例。现在你来
设计一个硬件设备调试系统。
图2-3 架构设计过程是一棵决策树(切分类决策)
图2-4 架构设计过程是一棵决策树(技术选型类决策)第1步,理解需求——此时软件系统是黑盒子
如图2-5所示,你要设计的系统现在还未切分,它的主要需求目标
有:
· 作为设备调试系统,其主要功能是实时显示设备状态,以及支
持用户发送调试命令;
· 另外,由于是为硬件产品配套的软件系统,所以它必须容易被
测试,否则是硬件故障还是软件故障将很难区分;
· 再就是必须具有很高的性能,具体性能指标为“每秒钟能够刷
新 5 次设备状态的显示,并同时支持一个完整命令字的发送”。
第2步,首轮决策——此时软件系统被高层切分
之后,软件架构师必须规划整个系统的具体组成。通常,对于一
个独立的软件系统而言,它常常被划分为不同的子系统或分系统,每
个部分承担相对独立的功能,各部分之间通过特定的交互机制进行协
作。
图2-5 设备调试系统:主要目标(CRC卡)
而此例中的设备调试系统则不同,它有两个相对独立的应用组
成:一个桌面应用和一个嵌入式应用。
那么,它们如何通信呢?最终决定,将它们通过串口连接,采用
RS232协议进行通信。
再接下来,架构师必须决定这两个应用分别担负哪些职责(如图
2-6 中的 CRC 卡所示):桌面应用部分负责提供模拟控制台和状态显示;而嵌入式应用部分负责设备的控制和状态数据的读取。
图2-6 设备调试系统:组成部分(CRC卡)
第3~N步,继续决策——此时软件系统被切分成更小单元……现在,设备调试系统的桌面应用部分,也要划分成模块吧
(如图2-7所示)。
通信部分被分离出来作为通信层,它负责在 RS232 协议之上实现
一套专用的“应用协议”:当应用层发送来包含调试指令的协议包
时,它会按 RS232 协议将之传递给嵌入部分;当嵌入部分发送来原始
数据时,它将之解释成应用协议包发送给应用层。
而应用层负责设备状态的显示,提供模拟控制台供用户发送调试
命令,并使用通信层和嵌入部分进行交互。……如此步步设计下去,你就该问自己“架构的哪些目标还未达
成”诸如此类的问题了。例如“应用层”怎样高速响应用户?例如
“通信层”如何高性能地接受串口数据而不造成数据丢失?在此不再
赘述。图2-7 其中的桌面应用:进一步分解(CRC卡)
2.2.3 系统、子系统、框架都可以有架构
虽然我们最常听到的说法是“软件系统的架构”,但未必是完整
的软件系统才有架构。真实的软件其实是“由组件递归组合而成”
的,图2-8运用Composite模式刻画了这一点:
· 组件的粒度可以很小,也可以很大;任何粒度的组件都可以组
合成粒度更大的整体。即所谓的粒度多样性问题;
· 组件粒度的界定,必须在具体的实践上下文中才有意义;你的
大粒度组件,对我而言可能是原子组件。即所谓的粒度相对性问题;
· 组件分为原子组件和复合组件两种;在特定的实践上下文中,原子组件是不可再分的;复合组件是由其他组件(既可以是原子组
件,又可以是复合组件)组合而成的;无论是原子组件还是复合组
件,它们之间都可以通过交互来完成更复杂的功能。图2-8 借助Composite模式刻画真实的软件
是时候为“软件架构”找准位置了,答案看上去惊人的简单(如
图2-9所示):
· 架构设计是针对作为复合整体的“复杂软件单元”的,架构规
定了“复杂软件单元”如何被设计的重要决策;
· 实际上,系统、子系统和框架(Framework)根据需要都可以
进行架构设计。图2-9 为“软件架构”找准位置
例如,航空航天领域的系统往往极为复杂,这样一来,总的系统
需要配备系统架构师,子系统有时也会分别单独配备架构师。
又例如,用友华表 Cell 组件是标准的报表处理 ActiveX 组件,它提供几百个编程接口。虽然在用户看来它只是小小的“开盒即用”
的ActiveX 组件(上面说的“原子组件”),但它的研发团队从需求
分析到架构设计到程序开发……都样样经历(上面说的“复杂软件单
元”)。
再例如,随着面向服务架构(Service Oriented Architecture,SOA)被越来越多的人所接受,基于组件的软件工程(Component
Based Software Engineering,CBSE)也为更多的人所认识。在此种
情况下,整个系统的架构模式是 SOA,而每个组件本身也有自己的架
构设计——在实践中不了解这一点会很危险。
推广开去,其实任何作为复合整体的复杂事物都可能有架构,比
如一本书、一幢建筑物。那本“永不褪色的经典”《如何阅读一本书》中就说:“每一本书的封面之下都有一套自己的骨架(Every
book has a skeleton hidden between its boards)。”
2.3 实际应用(1)——团队对架构看法不一怎么办
2.3.1 结合手上的实际工作来理解架构的含义
你们公司,你所在的部门,是否存在这样的问题:不同的人对架
构有不同的理解?
看法影响做法。先说程序员。如果程序员们对他们公司架构师的
做法“不以为然”,会不会不按照架构进行后续的详细设计和编程
呢?……这让我们不禁想到,程序代码实际体现的设计和《架构设计
文档》差别很大,是很多公司都存在的现象。这背后,难道没有“程
序员和架构师对架构有不同的理解”这一原因吗!
再说架构师。如果一个架构师认为“架构就是通用模块”,那么
他可能就不会关心非通用单元的设计。如果一个架构师认为“架构就
是技术选型”,那么他在拍板儿选择“Spring+S truts”之后就理所
当然地无事可做了。如果一个架构师认为“投标时讲的架构就是架构
的全部”,那么他才不管那“三页幻灯”对程序员的实际开发指导不
够呢(因为没有意识到)。
怎么办呢?
一通理论说教是不行的。太空洞,到了实际工作中,理解依然、做法照旧。
结合手上的实际工作来理解架构的含义,是笔者推荐的做法。
2.3.2 这样理解“架构”对吗
某公司,研发二部,他们一直在做的软件产品叫PM Suite,是一
套项目管理系统。
老王,研发二部部长,经验丰富、设计功力也非常深厚。
小张,众多程序员的代表,开发骨干,功底扎实、头脑灵活、工
作努力。小张希望能在 1~2年之内,从程序员转型成为架构师。关于“什么是架构”,小张是这么理解的:
在一些大型项目或者大型公司里,都是由架构师编写出系统接
口,具体的实现类交给了程序员编写,公司越大这种情况越明显,所
以在这些公司里做开发,我们可能都不知道编写出的系统是个什么样
子,每天做的工作可能就是做“填空题”了。
当你发现越来越灵活地使用接口时,那么你就从程序员升级为架
构师了。
老王用3个公式概括了一下小张的理解:
程序=类+类级接口
架构设计=定义类级接口
编程开发=像做填空题似的写实现类
这可行吗?将架构设计一下子细致到类:一是难度太大不现实,二是工作量太大没必要,三是并发呀部署呀都没考虑、性能安全可伸
缩等需求能达标?……于是老王开始担心了。
2.3.3 工作中找答案:先看部分设计
老王找来小张,铺开纸笔,开始拿实际工作来“说事儿”。他
说:
咱们的 PM Su ite 系统,有一项名为“查看甘特图”的需求,用
户要求“能够以甘特图方式查看任务的起始时间、结束时间、任务承
担者等信息”。经过分析我们不难发现,PM Suite 至少应提供两种查
看任务计划的方式:一种是以表格的方式将任务名称、开始时间等信
息列出,另一种是采用甘特图。如图2-10所示。图2-10 PM Suite至少要提供两种查看任务计划的方式
任务是如何计划的?又具体分配给哪些项目成员?这些信息和 PM
Su ite 采用何种方式来展现应当是没有关系的。根据此分析,我们立
即想到采用 MVC 架构,将业务逻辑和展现逻辑分开,如图2-11所示。
图2-11 和具体技术无关的架构方案上面的架构设计,还处于“和具体技术无关”的层面。我们必须
考虑更多的实际开发中要涉及的技术问题,从而不断细化架构方案,这样才能为开发人员提供更多的指导和限制,也才能真正降低后续开
发中的重大技术风险。
对于 PM Suite 要显示甘特图而言,“甘特图绘制包”是自行开
发的,还是采用的第三方SDK,就是一个很重要的技术问题。考虑如
下:
· 一方面,用户根本不关心“甘特图绘制包”的问题,他们只在
乎自己的需求是否得到了满足;而项目工期是很紧的,自行开发“甘
特图绘制包”势必增加其他工作的压力,为什么不采用第三方SDK呢?
· 另一方面,短期内决定采用的第三方“甘特图绘制包”可能并
不是最优的,所以并不希望PM Suite“绑死”在特定“甘特图绘制
包”上。
基于以上分析,架构师会决定:采用第三方 SDK,但会自主定义
“甘特图绘制接口”将SDK隔离。如图2-12所示。图2-12 和技术相关的架构方案
有的读者应该已经看出来了,上述设计中采用了Adapter设计模
式。
适配器(Adapter)模式
关键字:已存在不可预见 复用
支持变化:由于 Adapter 提供了一层“间接”,使得我们可以复
用一个接口不符合我们需求的已存在的类,也可以使一个类
(Adaptee)在发生不可预见的变化时,仅仅影响 Adapter而不影响
Adapter的客户类。
结构:
2.3.4 工作中找答案:反观架构概念的体现
看到小张听得挺有感觉,老王话锋一转,话题落于架构的理解
上。他说:
有关PM Suit e的设计,先讲到这儿,我再简单说一下“什么叫架
构”。架构的定义很乱,但可以分为两派。
组成派:架构=组件+交互
决策派:架构=一组重要决策刚才有关 PM Suite 的设计虽然仅涉及架构的“冰山一角”,但
仍然可以体现软件架构的概念——对组成派和决策派的架构概念都有
体现。
先说组成派的架构概念,它强调软件架构包含了“计算组件及组
件之间的交互”。组件体现在哪里呢?
· 【回顾图 2-11】 。“业务层”和“展现层”就是两个组
件;当然,这两个组件粒度很粗,并且完全是黑盒。
· 【到了图 2-12】 。为了支持 MVC 协作机制,设计中引入了
PrgMgtModel、GanttChart和 GanttChartImpl 等关键类。可以说,“业务层”和“展现层”两个组件在某种程度上已从黑盒变成了灰
盒,从而能提供更具体的开发指导。
那么,软件架构概念中所说的“交互”体现在哪里呢?
· 【回顾图 2-11】 。“业务层”和“展现层”两个粗粒度组
件之间的交互为:展现层从业务层“读取数据”。
· 【到了图 2-12】 。“读取数据”这一交互已经“具体落
实”成了“GanttChartImpl 从PrgMgtModel读取数据”。另外,图中
还有两个“调用”关系。
由此看来,组成派软件架构概念完全是对架构设计方案的忠实概
括,只不过有一点儿抽象罢了。
再看看决策派的架构概念,它归纳了架构决策的类型,指出架构
决策不仅包括关于软件系统的组织、元素、子系统、架构风格等的几
类决策,还包括关于众多非功能需求的决策。
· 【回顾图 2-11】 。业务层和展现层分离,体现了架构概念
中的“软件系统的组织”决策,业界也普遍认同。
· 【到了图2-12】 。为了防止PM Suite“绑死”在特定甘特图
绘制包上,设计中引入自主定义的GanttChart接口,让实现该接口的
GanttChartImpl转而调用第三方SDK(其实就是 Adapter 设计模
式)。这样一来,架构就有了弹性——当发现功能更强大的甘特图程
序包时(或决定直接调用Java 2D自行开发甘特图绘制部分时),可以
方便地仅更改GanttChartImpl,而其他组件不用更改(如图2-13所
示)。图2-13 软件架构如何具有弹性
老王最后说:呵呵,组成派和决策派无非是个叫法,它们只不过
是所站的角度不同罢了,你在具体设计一个架构时都会有所体现的。第3章 理解架构设计视图
“有角度就有空间”。……多视图方法背后的核心思想有些相
似:从不同角度,规划“分割”与“交互”。
——温昱,《一线架构师实践指南》
不同的视图支持不同的目标和用途。
——Paul Clements,《软件构架编档》
架构设计是一门解决复杂问题的艺术。
设计任何复杂系统时,架构视图都是不可或缺的(无一例外)。
但由于在日常开发工作中较少接触,大部分程序员对“设计视图”的
思想还比较陌生。
本章围绕“架构视图”这一主题,将逐次讨论:
· 设计架构时,架构视图为什么必不可少?【本章问题1】
· 什么是架构视图?【本章问题2】
· 如何运用“逻辑视图+物理视图”设计一个系统的架构?【本
章问题3】
3.1 软件架构为谁而设计
办公室里,关于什么是软件架构,争论正酣。
程序员说 ,软件架构就是要决定需要编写哪些 C 程序或 OO
类、使用哪些现成的程序库(Library)和框架(Framework)。程序
经理笑了 。
程序经理说 ,软件架构就是模块的划分和接口的定义。系统分
析员笑了 。
系统分析员说 ,软件架构就是为业务领域对象的关系建模。配
置管理员笑了 。
配置管理员说 ,软件架构就是开发出来的以及编译过后的软件到
底是个啥结构。数据库工程师笑了 。数据库工程师说 ,软件架构规定了持久化数据的结构,其他一切
只不过是对数据的操作而已。部署工程师笑了 。
部署工程师说 ,软件架构规定了软件部署到硬件的策略。用户
笑了 。
用户说 ,软件架构应该将系统划分为一个个功能子系统。程序员
又笑了 。
大家想了想说 ,我们都没错呀,所有这些方面都是需要的啊。……软件架构师哭了 。
由此看来,不同涉众看待架构的视角是不同的,而架构师要为不
同的涉众而设计。
怎么办呢?同时关注多个架构设计视图。架构视图的本质是“分
而治之”,能帮助架构师从不同角度设计,特别是面对复杂系统时
“分而治之”地设计是必需的。
这就回答了“设计架构时,架构视图为什么必不可少”的问题
【本章问题1】 。
3.1.1 为用户而设计
为什么要开发某个软件系统呢?因为要给用户使用:或辅助用户
完成日常工作,或帮助用户管理某些信息,或给用户带来娱乐体
验……不一而足。
用户要功能,用户也要质量。
每套软件都会提供这样或那样的功能,正是这些功能帮助用户实
现他们在工作或生活中的特定目标。用户所需的功能和系统本身的结
构一定是相互影响的,这正是软件架构师要特别关注的。先举个生活
中的例子吧。例如,因为功能不尽相同,所以“转笔刀”的结构和
“专用刀片”的结构也不一样(如图 3-1 所示):小学生需要削铅
笔,那一定是转笔刀最适合他们,因为方便易用,一转即可;而美术
师需要用铅笔来画素描,他们则需要使用专用刀片,因为转笔刀难以
削出满足不同绘画要求的形状各异的笔尖。同样,对于软件系统而
言,用户需求是千差万别的,我们采用的软件架构必须和所要提供的
功能相适应。因此,软件架构师必须时时牢记:为用户而设计。图3-1 生活中的例子:功能与结构相互影响
诸如性能、易用性等软件质量属性,并不像上面所述的软件功能
那样直接帮助用户达到特定目标,但并不意味着软件质量属性不是必
需的——恰恰相反,质量属性差的软件系统大多都不会成功。例如,你提供了用户要求的“交易查询”功能,但这一功能动辄就需要花上
几分钟,用户能接受吗?当然不能接受。用户会说,功能虽然具备
了,但质量太差难以接受。用户在使用软件系统的过程中,其关心的
质量属性可能包括易用性、性能、可伸缩性、持续可用性和鲁棒性
等。因此,软件架构师也应当时时牢记:为用户而设计,不仅满足用
户要求的功能,也要达到用户期望的质量。
3.1.2 为客户而设计
很多时候,客户(Customer) ≠ 最终用户(User)。
例如,对超市销售系统而言,客户是某家连锁超市(的老板),而用户则是超市收银员和上货员。
架构师为客户而设计:充分考虑客户的业务目标、上线时间的要
求、预算限制,以及集成需要等,还要特别关注客户所在领域的业务
规则和业务限制。为此,架构师应当直接或(通过系统分析员)间接
地了解和掌握上述需求及约束,并深刻理解它们对架构的影响,只有
这样才能设计出合适的软件架构。合适的才是最好的,例如,如果客
户是一家小型超市,软件和硬件采购的预算都很有限,那么你就不宜
采用依赖太多昂贵中间件的软件架构设计方案。
3.1.3 为开发人员而设计先研究需求,再设计架构,然后交由开发人员编程……作为架
构,不仅要为“上游”的需求而设计,还要为“下游”的开发人员而
设计。
例如,性能是软件运行期质量属性,最关心性能的人其实是客
户;但可扩展性是软件开发期质量属性,项目开发人员和负责升级维
护的开发人员最关心。
推及开去,其实,并不是所有需求都来自用户,软件的可扩展
性、可重用性、可移植性、易理解性和易测试性等非功能需求更多地
考虑对开发人员的影响。这类“软件开发期质量属性”深刻影响开发
人员的工作,使开发更顺畅抑或更艰难。
3.1.4 为管理人员而设计
软件变得越来越复杂,单兵作战不再普遍,取而代之的是团队开
发。而团队开发又反过来使软件开发更加复杂,因为现在不仅仅要面
临技术复杂性的问题了,还有管理复杂性的问题。
开发人员之间的依赖,源自他们负责的程序之间的依赖(如图 3-
2 所示)。要理清并管理人员协作,就应该搞清楚系统一级“模块+交
互”的设计,搞清楚架构。可见,架构是开发管理的核心基础。
图3-2 开发人员之间的依赖,源自他们负责的程序之间的依赖
看来,软件架构师也应为管理人员而设计。例如,对软件项目管理而言,软件架构应当起到应有的作用:为
项目经理制定项目计划、管理项目分工和考核项目进度等提供依据。
一方面,软件架构从大局着手,就技术方面的重大问题作出决策,构
造一个由粗粒度模块组成的解决方案,从而可以把不同模块分配给不
同小组分头开发。另一方面,软件架构设计方案规定了各模块之间如
何交互的机制和接口,在开发小组之间起到“沟通桥梁”和“合作契
约”的作用。
再例如,对软件配置管理而言,软件架构师亦应顾及。一般而
言,在软件架构确定之前,软件配置管理是无法全面开展的。配置管
理员应该能够从软件架构方案中了解到开发出来的软件以什么样的目
录结构存在,以及编译过后的软件目标模块放到哪个目录等决定,并
以此作为制定配置管理基本方案的基础。
3.1.5 总结
架构师应当为项目相关的不同角色而设计(如图 3-3 所示)——
只有这样,软件架构才能和它“包含了关于如何构建软件的一些最重
要的设计决策”的“地位”相符。
图3-3 软件架构为谁而设计· 架构师要为“上游”客户负责,满足他们的业务目标和约束条
件;
· 架构师要为“上游”用户负责,使他们关心的功能需求和运行
期质量属性得以满足;
· 架构师必须顾及处于协作分工“下游”的开发人员;
· 架构师还必须考虑“周边”的管理人员,为他们进行分工管
理、协调控制和评估监控等工作提供清晰的基础。
3.2 理解架构设计视图
什么是架构视图呢?【本章问题2】
3.2.1 架构视图
架构视图的实践导向性很强,每个视图分别关注不同的方面,针
对不同的实践目标和用途。Philippe Kruchten在其著作《Rational统
一过程引论》中写道:
一个架构视图是对于从某一视角或某一点上看到的系统所作的简
化描述,描述中涵盖了系统的某一特定方面,而省略了与此方面无关
的实体。
架构视图是一种设计架构、描述架构的核心手段:
· 也就是说,架构要涵盖的内容和决策太多了,超过了人脑“一
蹴而就”的能力范围,因此采用“分而治之”的办法从不同视角分别
设计;
· 同时,也为软件架构的理解、交流和归档提供了方便。
在多种架构视图中,最常用的是逻辑架构视图和物理架构视图
(本章稍后讨论如何运用“逻辑视图+物理视图”设计架构)。
3.2.2 一个直观的例子
在讲解软件的逻辑架构视图和物理架构视图之前,先看一个生活
中视图的例子。图 3-4 所示的世界人口分布图,是社会学家关心的;而气候学
家,则更关心图 3-5 所示的世界年降水量分布图。这其实就运用了
“视图”的手段,用不同视图来刻画我们关心的世界的不同方面——
你完全可以将“世界人口分布图”称为“世界的人口分布视图”。
当然,更进一步而言,同一事物的不同视图之间是有联系的。例
如,从图 3-4 和 3-5 上看,除了南美洲之外基本都是降水量足的地
方人口较密集。我们下面将讨论的软件架构视图也是这样,不同视图
之间存在相互影响。
图3-4 世界人口分布图(图片来源:www.dlpd.com)图3-5 世界年降水量分布图(图片来源:www.dlpd.com)
3.2.3 多组涉众,多个视图
首先,考虑软件架构的表达与交流。
这是个很现实的问题。究其原因,由于角色和分工不同,整个软
件团队以及客户等涉众各自需要掌握的技术或技能存在很大差异,为
了完成各自的工作,他们需要了解整套软件架构决策的不同子集。所
以,软件架构师应当提供不同的软件架构视图,以便交流和传递设计
思想。例如:
· 系统工程师:由于负责部署和运营维护,他们最关心软件系统
基于何种操作系统之上、依赖于哪些软件中间件、有没有群集或备份
等部署要求、驻留在不同机器上的软件部分之间的通信协议是什么等
决策;
· 而开发人员:则最关心软件架构方案中关于模块划分的决定、模块之间的接口如何定义、甚至架构指定的开发技术和现成框架是不
是最流行的等问题;……
不一而足。相反,如果不同视图混为一谈,《架构文档》理解起来会非常困
难、甚至看不懂。对此,Peter Herzum等人在Business Component
Factory一书中曾指出:
总的来说,“架构”一词涵盖了软件架构的所有方面,这些方面
紧紧地缠绕在一起,决定如何将之分割成部分和主题显得相当主观。
既然如此,就必须引入“架构视点”作为讨论、归档和理解大型系统
架构的手段。(Generally speaking,the term architecture can
be seen as covering all a spects of a soft ware architect
ure.All its aspects re deeply intertwined,an d it is really
a subj ective decisi on to split it up in parts and su
bjects.Having said that , the u sefulness of int roducing
archit ectural viewp oints is e ssential as a way of
discussing,documenting,and mastering the architecture of
large-scale systems.)
第二,考虑软件架构的设计。
这个问题更为关键。软件架构是个复杂的整体,架构师可以“一
下子”把它想清楚吗?当然不能。有关思维的科学研究表明,越是复
杂的问题越需要分而治之的思维方式:
· 将“架构视图”作为分而治之的手段,使架构师可以分别专注
于架构的不同方面,相对独立地分析和设计不同“子问题”,这相当
于将“整个问题”简化和清晰化了;
· 再也不必担心逻辑层(Layer)、物理层(Tier)、功能子系
统、模块、接口、进程、线程、消息和协议等设计统统混为一“潭”
(泥潭?)了。
不幸的是,大多数书籍中都强调多视图方法是软件架构归档的方
法,却忽视了该方法对架构设计思维的指导作用。而本书强调,多视
图不仅是归档方式,更是架构设计的思维方式。
3.3 运用“逻辑视图+物理视图”设计架构
无论是软件架构,还是现实生活,运用“逻辑视图+物理视图”刻
画大局,都方便有效。图 3-6 所示为办公室局域网:从物理角度看,所有计算机“毫无区别”地连接到路由器上;而从逻辑角度看呢,一
台计算机充当文件服务器,而其他计算机是可以访问服务器的客户
机。
图3-6 区分物理视角与逻辑视角
那么,如何运用“逻辑视图+物理视图”设计一个系统的架构呢?
【本章问题3】
3.3.1 逻辑架构
软件的逻辑架构规定了软件系统由哪些逻辑元素组成以及这些逻
辑元素之间的关系。具体而言,组成软件系统的逻辑元素可以是逻辑
层(Layer)、功能子系统、模块。
设计逻辑架构的核心任务,是比较全面地识别模块、规划接口,并基于此进一步明确模块之间的使用关系和使用机制。图3-7展示了一
个网络设备管理系统逻辑架构设计的一部分,“模块+接口”是其设计
的基本内容:
· 识别模块(例如,图中的TopoGraphModel等);
· 规划模块的接口(例如,图中的StatusChangedRender等);
· 明确模块之间的使用关系和使用机制(例如,图中的
StatusChanged 是由GeneralModel创建的消息,以参数的形式传递给StatusChangedRender接口)。
图3-7 软件逻辑架构设计的核心任务
3.3.2 物理架构软件的物理架构规定了组成软件系统的物理元素,这些物理元素
之间的关系,以及它们部署到硬件上的策略。
物理架构可以反映出软件系统动态运行时的组织情况。此时,上
述物理架构定义中所提及的“物理元素”就是进程、线程,以及作为
类的运行时实例的对象等,而进程调度、线程同步、进程或线程通信
等则进一步反映物理架构的动态行为。
随着分布式系统的流行,“物理层(Tier)”的概念大家早已耳
熟能详。物理层和分布有关,通过将一个整体的软件系统划分为不同
的物理层,可以把它部署到分布在不同位置的多台计算机上,从而为
远程访问和负载均衡等问题提供了手段。当然,物理层是大粒度的物
理单元,它最终是由粒度更小的组件、模块和进程等单元组成的。
物理架构的应用很广泛。例如,架构设计中可能需要专门说明数
据是如何产生、存储、共享和复制的,这时可以利于物理架构,展示
软件系统在运行期间数据是由哪些运行时单元产生以及是如何产生
的、数据又如何被使用、如何被存储、哪些数据需要跨网络复制和共
享等方面的设计决策。
由此可见,对于“逻辑架构+物理架构”这个“2 视图方法”而
言,组成软件系统的“物理元素”涉及的内容比较宽泛,如图 3-8 所
示。(也正是因为这个原因,设计大型系统的架构时会引入更多架构
设计视图,从而使每个视图的设计内容更加明确,本书后续要讲的5视
图法包含了逻辑架构、开发架构、运行架构、数据架构和物理架
构。)图3-8 “2视图方法”的物理架构可能的设计内容
3.3.3 从“逻辑架构+物理架构”到设计实现
架构设计,指导后续的详细设计和编程;而详细设计和编程,贯
彻和利用这些设计(如图3-9所示):
· 逻辑架构中关于职责划分的决策,体现为层、功能子系统和模
块等的划分决定,从静态视角为详细设计和编程实现提供切实的指
导;有了分解就必然产生协作,逻辑架构还规定了不同逻辑单元之间
的交互接口和交互机制,而编程工作必须实现这些接口和机制。
· 所谓交互机制,是指不同软件单元之间交互的手段。交互机制
的例子有:方法调用、基于RMI的远程方法调用、发送消息等。
· 至于物理架构,它关注的是软件系统在计算机中运行期间的情
况。物理架构设计视图中规定了软件系统如何使用进程和线程完成期
望的并发处理,进程线程这些主动单元(Active Unit)会调用哪些被
动单元(Passive Unit)参与处理,交互机制(如消息)为何等问
题,从而为详细设计和编程实现提供切实指导。图3-9 逻辑架构和物理架构对后续开发的作用
3.4 实际应用(2)——开发人员如何快速成长
3.4.1 开发人员应该多尝试设计
你们公司,你所在的部门,发现了一个问题,即“兵多将少”。
程序员足够多但设计人员太少。
设计不满意似乎成了常态……
诸如相似模块的低水平重复开发等困扰挥之不去……
部门的总体工作效率低下……
你们会也开了,问题也讨论了,问题背后的问题也被“揪”出来
了——开发人员的成长速度低于预期。
怎么办呢?
如果你是程序员,又盼着有一天能做架构师,就要明白“经历设
计在前,成为架构师在后”的道理。也就是说,程序员要尽量找机会
多看看别人的设计成果、多体会别人的设计过程、多试着自己来设计
设计——这些方式都能促进对设计方法或技巧的领会。
如果你是主管,又深感手下“兵多将少”设计人才短缺,就要确
认一下是不是给程序员接触设计的机会太少了。也就是说,主管应该尽量创造机会让程序员多看看别人的设计成果、多体会别人的设计过
程、多试着自己来设计设计。
笔者的经验表明,结合培训、让开发人员对实验项目进行设计,也不失为一种快速提升设计技能的好办法。
3.4.2 实验项目:案例背景、训练目标
下面,我们来设计一个名为MailProxy的邮件代发系统。
众多公司的“客户服务系统”都需要批量地向客户发送邮件。
(“客户服务系统”管理着企业对客户的服务内容,包括客户投诉、故障处理、客户咨询、客户查询、客户回访、客户建议、客户关怀等
服务信息以及服务指标信息等。)而 MailProxy 作为一款软件产品,其核心功能就是:邮件代发。图3-10所示的用例图刻画了MailProxy的
基本功能:
· MailProxy和客户系统对接;
· 通过对Mail Server系统的调度完成自动邮件代发;
· 反馈发送结果给客户系统(含Log日志等);
· 还提供灵活的规则设置等功能。图3-10 MailProxy系统的用例图
“训练”目标:
· 运用本章所讲的“逻辑视图+物理视图”技能。
· 辅以分而治之、迭代式设计两个技巧:
【分而治之】 。逻辑架构进行“逻辑分解”,物理架构进行“物
理分解”,它们分别关注架构的不同方面,利于思维聚焦(相当于化
“大问题”为“子问题”)。
【迭代式设计】 。不同架构视图的设计交替进行、迭代展开。逻
辑职责的划分逐步清晰,促进了物理分布设计;反之亦然(死抠“未
知”抠不出来,就利用当前“已知”探索更多“未知”,循环着来
嘛)。
3.4.3 逻辑架构设计(迭代1)……深入研究需求之后,发现 MailProxy 系统的一个显著特点:
不仅要和“人”交互,更要和多种“外部系统”交互。
因此,设计逻辑架构时,除了包含用户交互层、业务逻辑层、数
据访问层之外,一定应包含一个“系统交互层”(如图3-11所示)。
图3-11 着手设计逻辑架构:分层
3.4.4 物理架构设计(迭代1)
多视图≠多阶段,不应瀑布式地设计每个视图,而是应该迭代式
设计。而且,对大型系统而言,先把逻辑架构详尽地设计完再开始物
理架构的设计,有很大的问题:
· 一是比较困难。毕竟,逻辑架构、物理架构是同一系统的不同
方面;如果系统比较复杂,在对一个方面的设计毫无所知的情况下,过于深入设计的另一方面太过盲目了。
· 二是不利于提高设计质量。而逻辑架构、物理架构交替进行,本身就是不断相互验证、促进设计优化的过程。
应该早些开始物理架构视图的设计。现在,着手设计 MailProxy
的物理分布,如图 3-12所示。图3-12 着手设计物理架构:基本的物理分布
3.4.5 逻辑架构设计(迭代2)
原先接手MailProxy时,对它相当陌生。
设计逻辑架构时,确立了基本分层结构之后就感觉后续设计“展
不开”、“细不下去”。
现在,有了初步的逻辑分层、还有基本的物理分布设计,转回头
来再继续逻辑架构设计试试。……嗯,根据物理架构的提示,逻辑层
“系统交互层”中应该有“Mail Server 交互”模块吧,它封装和具
体 Mail Server 的交互。……嗯,“用户交互层”应当有“设置地
址”、“设置规则”等UI模块。
逐步细化逻辑架构的设计,得到图3-13所示的逻辑架构。图3-13 细化逻辑架构的设计:模块划分
好多逻辑模块呀,把它们划归 3 个工程(Project),这就意味
着 MailProxy 发布时将包含 3个目标程序单元(图3-14描述了3个目
标程序单元的关系):
· 后台服务器程序。
· 管理员Web应用。
· 代理模块(相当于 MailProxy 系统专门发布给合作开发单位
的 API。这样,客户系统只需改动最少的代码就可以与 MailProxy 互
联互通。运行时,客户系统必须包含代理模块的相应Library文件。)图3-14 细化逻辑架构的设计:明确MailProxy包含的程序单元
3.4.6 物理架构设计(迭代2)
继续迭代设计。
上面的逻辑架构设计逐步清晰、不同模块不断明确、相应的目标
程序组件也都清楚了,使你能进一步设计物理架构了。如图 3-15 所
示,软件单元和硬件机器的映射关系进一步明确了,这就为未来的安
装部署方式提供了指导。图3-15 细化物理架构的设计:软件如何部署到硬件
嘿,多个视图之间来回迭代着进行设计,思路清晰、效果不错。第2部分 实践过程篇
第4章 架构设计过程
作为职业软件人,我们都寻求使用一种有效而经济的过程,来建
造一个能够工作的、有用的产品。
——Grady Booch,Rational公司首席科学家
每个项目都是很独特的,因此开发人员必须努力保持微观过程的
非正式性和宏观过程的正式性之间的平衡。
——Grady Booch,《面向对象分析与设计》
程序员向架构师转型,难在何处?难在必须要能开始“试着做起
来”,并慢慢积累感觉,进而积累经验。
“需求决定架构”之所以是一句废话,就是因为它没告诉开发人
员“架构设计怎么做”。
甚至,在没有积累任何经验和“感觉”的情况下,忽然被老板
“委以重任”负责架构设计,都未必是一件好事。因为这次失败了,下次机会就没了。
本章通过下述方式,讲清楚架构设计过程的大局,希望帮助程序
员能将架构设计“试着做起来”:
· 架构设计过程包含哪些步骤?
· 步骤之间什么关系?下游步骤的“输入”依赖的是上游步骤的
哪个“输出”?
4.1 架构设计的实践脉络
4.1.1 洞察节奏:3个原则
成功的架构设计是相似的,失败的架构设计各有各的原因。如下3
个原则也可以被视为做好架构设计的3个必要条件:
· 【原则1】 看透需求· 【原则2】 架构大方向正确
· 【原则3】 设计好架构的各个方面
这3个原则,基本框定了整个架构设计过程的节奏。也就是说(如
图4-1所示):
· 最先,要看透需求,这是基础。架构师可能不是“需求”和
“领域模型”的负责人,但也必须深入了解。
· 中间,确定正确的概念架构。“关键需求”决定“概念架
构”。
· 最后,充分设计架构的各个方面。通过多视图方法“细化架
构”,通过“架构原型”验证架构。
图4-1 架构设计过程的节奏
【原则1】看透需求
架构设计可谓影响深远:一是它决定了系统的整体质量进而决定
了客户的满意度,二是它决定了开发人员开发、维护和扩展程序的容
易程度。
看透需求,简单说就是设计人员要做到“理解了、能说出所以然
来”。必须的!众所周知。
看透需求,不仅要把需求找全,还要把需求项之间的矛盾关系、追溯关系也都搞清楚:· 需求要全。
——举例:重视“功能”忽视“质量”,危险;重视“A 质量”
忽视应有的“B 质量”,危险;忘了来自甲方乙方第三方的“约
束”,危险。功能需求、质量需求、约束需求都要定义清楚。
——处理:发现需求遗漏,就要尽快把遗漏的需求研究清楚。
· 矛盾关系。
——举例:安全性和互操作性有矛盾,可扩展性和性能有矛盾,功能强大和预算有限有矛盾……
——处理:识别出需求间的矛盾还没完,要给对策(例如性能最
重要、可扩展性折衷,或者相反首先照顾可扩展性)、甚至重新评审
需求的合理性。
· 追溯关系。
——举例:“需求范围”合理吗?要向前追溯“系统目标”。符
合目标要求、能帮助实现目标,才合理。
——举例:“用例图”或者“功能项定义”,是否覆盖了更高层
需求之“需求范围”。
——处理:下层需求没有覆盖上层需求,必有需求遗漏。下层需
求超出了上层需求,恐怕存在需求镀金现象。
——说明:一个成功的软件系统,对客户高层而言能够帮助他们
达到业务目标,这些目标就是客户高层眼中的需求;对实际使用系统
的最终用户而言,系统提供的能力能够辅助他们完成日常工作,这些
能力就是最终用户眼中的需求;对开发者而言,有着更多用户没有觉
察到的“需求”要实现……需求是分层次的。
【原则2】架构大方向正确
架构大方向正确是一种策略,先设计概念架构。
一个产品与类似产品在架构上的不同,其实在概念架构设计时就
大局已定了。
它不关注明确的接口定义(之后的细化架构设计才是“模块+接
口”一级的设计),对大型系统而言,这一点恰恰是必需的。概念架构一级的设计更重视“找对路子”,像架构模式啦、集成技术选型
啦……比较策略化。
【原则3】设计好架构的各个方面
架构师必须具备“忘却”的能力,避免涉及太多具体的技术细
节,但是大型软件架构依然是复杂的。这就要求从多个方面进行架构
设计,运用“多视图设计方法”:
· 例如,为了满足性能、持续可用性等方面的需求,架构师必须
深入研究软件系统运行期间的情况,权衡轻重缓急,并制定相应的并
行、分时、排队、缓存和批处理等设计决策。(运行架构视图)
· 而要满足可扩展性、可重用性等方面的需求,则要求架构师深
入研究软件系统开发期间的代码文件组织、变化隔离和框架使用等情
况,制定相应的设计决策。(开发架构视图)
·……本书推荐5视图方法:逻辑视图、开发视图、物理视图、运
行视图、数据视图。
实际经验表明,越是复杂的系统,越需要从多个方面进行架构设
计,这样才能把问题研究和表达清楚。Grady Booch 在其著作《UML
用户指南》中指出:“如果选择视图的工作没有做好,或者以牺牲其
他视图为代价只注重一个视图,就会冒掩盖问题以及延误解决问题
(这里的问题是指那些最终会导致失败的问题)的风险。”
【强调】培训中发现的问题(关于原则2)
笔者在和企业的深入接触中发现,项目经理、架构师和总工等角
色“最深有感慨”的就是“架构大方向正确”原则,但很多程序开发
人员对此则“感触不深”。在此,希望程序开发人员稍微留意,概念
架构是直指系统设计目标的设计思想和重大选择——是关乎任何复杂
系统成败的最关键的、指向性的设计:
· 你作为架构师,设计大中型系统的架构时,会先对比分析几种
可能的概念架构。
· 看看竞争对手的产品彩页,上面印的架构图,还是概念架构。
· 如果你是售前,你又提到架构,这也是概念架构。
· 如果你去投标,你讲的架构,就是概念架构。架构新手和有经验架构师的区别之一,在于是否懂得、并能有效
地进行概念架构的设计。作为架构新手,尤其害怕碰上自己没做过的
系统;系统较大时,一旦祭出“架构=模块+接口”的法宝却不太奏
效,架构新手就往往乱了阵脚。相反,有经验的架构师不会一上来就
关注如何定义“接口”,他们在大型系统架构设计的早期比较注重识
别 1)重大需求、2)特色需求、3)高风险需求,据此来决定如何划
分顶级子系统、采用什么架构风格和开发技术、集成是否要支持、二
次开发是否要支持。
4.1.2 掌握过程:6个步骤
洞察了架构设计过程的节奏,再看步骤。整个架构设计过程,包
含 6 大步骤(如图 4-2所示):
(1)需求分析
(2)领域建模
(3)确定关键需求
(4)概念架构设计
(5)细化架构设计
(6)架构验证
至此,6步骤之间的关系也就不难理解了,如图4-3所示。
可以看出,架构设计的开展非常依赖其上游活动。总体而言,这
些上游活动包括需求分析和领域建模。图4-2 架构设计过程的6个步骤
图4-3 6个步骤之间的关系
需求分析。 毋庸置疑,在没有全面认识需求并权衡不同需求之间
相互影响的情况下,设计出的架构很可能有问题。
领域建模。 领域建模的目的是:透过问题领域的重重现象,捕捉
其背后最为稳固的领域概念,以及这些概念之间的关系。在项目前
期,所建立的领域模型将为所有团队成员之间、团队成员和客户之间
的交流提供共同认可的语言核心。随着项目的进展,领域模型不断被
精化,最终成为整个软件的问题领域层,该层决定了软件系统能力的范围。本书还认为,从项目前期伊始,软件架构师就应该是领域建模
活动的领导者,这样可以避免“不同阶段领域模型由不同人负责”所
带来的问题。
接下来要进行概念架构的设计。软件系统的规模越大、复杂程度
越高,进行概念架构设计的好处就越明显。
确定对架构关键的需求。 这不仅要求对功能需求(如用例)进
行筛选,还要对非功能需求进行综合权衡,最终确定对软件架构起关
键作用的需求子集。
概念架构设计。 概念架构的设计,必须同时重视关键功能和关键
质量。业界流行的一种错误观点是“概念架构=理想化架构”,不考虑
任何非功能需求,也不考虑任何具体技术。本书提出,概念架构要明
确给出“1 个决定 4 个选型”,即决定:1)如何划分顶级子系统;
2)架构风格选型;3)开发技术选型;4)集成技术选型;5)二次开
发技术选型。可以看出,其中涉及多项重大技术选型。
在接下来,全面展开规格级的架构设计工作,设计出能实际指导
团队并行开发的细化架构。
细化架构设计。 一般而言,可以分别从逻辑架构、开发架构、运
行架构、物理架构、数据架构等不同架构视图进行设计。
架构验证。 对后续工作产生重大影响返工代价很高的任何工作都
应该进行验证,软件需求如此,架构设计方案也是如此。至于验证架
构的手段,对软件项目而言,往往需要开发出架构原型,并对原型进
行测试和评审来达到;而对软件产品而言,可以开发一个框架
(Framework)来贯彻架构设计方案,再通过在框架之上开发特定的垂
直原型来验证特定的功能或质量属性。因此,从架构验证工作得到的
不应该仅仅是“软件架构是否有效”的回答,还必须有可实际运行的
程序:体现软件架构的垂直抛弃原型或垂直演进原型,或者是更利于
重用的框架。这些成果为后续的开发提供了实在的支持。
在通过后续各章展开讨论这些工作步骤之前,通过“速查手册”
的形式,再总体归纳一下每个工作步骤的主要输入、输出、关键技能
项。
4.2 架构设计的速查手册下面对架构设计的每个步骤,进行总括描述,供读者在“付诸实
践”时参考。
笔者建议,在系统地学习了第5~15章之后,请复习本节。本节所
采用的这种形式,也是笔者在架构培训的“总结回顾”环节所经常采
用的。效果不错!
4.2.1 需求分析
需求分析,是很多活动的统称,它是本书“架构设计过程”中第
1 个大的工作步骤。如图4-4所示。
需求分析活动输出的“需求”,必须涵盖功能、质量、约束这三
个方面,这些是后续设计活动所需要的。需求分析工作涉及的“技能
项”较多,总体而言可总结为“两纵三横”,如图 4-5所示:
· 【一纵】 需求沟通。持续伴随需求分析过程的,是需求沟
通、需求启发、需求验证等活动,这些活动都要求需方和开发方紧密
协同、精诚合作。“闭门造需”危险大了。
· 【二纵】 非功能需求的确定。真实的实践中,确定非功能需
求是一个持续的过程,是持久战。究其原因,这是非功能需求的范围
广造成的,无论是技术还是业务、无论是甲方还是乙方,都可能有这
样那样的非功能需求。想“一蹴而就”地定义非功能需求是不现实
的。图4-4 需求分析的“位置”
· 【三横】 需求分析主线。从确定系统目标开始,后续凭借
“范围+Feature+上下文图”三剑客研究高层需求,再后续建立开发人
员较熟悉的用例模型。
图4-5 需求分析的“技能项”和“输出”
做不到“追根溯源”的需求分析,往往会失败。因此,我们补充
图 4-6 来强调需求分析工作的主线是“确定系统目标→研究高层需求
→建立用例模型”,需求从“高飘”到“落地”,成果项从“目标列表”到“范围框图+Feature 树+上下文图”到“用例图+用例规约”,需求跟踪脉络清晰可辨。
更多内容,请阅读本书讲需求分析的章:第5章,需求分析;第6
章,用例与需求。
4.2.2 领域建模
领域建模,是以提炼领域概念,建立领域模型为目的的活动。领
域建模实践的精髓是“业务决定功能,功能决定模型”,理解了这个
理念,评审领域模型也变得再自然不过了。如图 4-7所示。
图4-6 需求分析的主线体现“追根溯源”图4-7 领域建模的“位置”
领域建模活动的输入:一是“功能”,二是“可扩展性”具体要
求(如图 4-8 所示)。说到底,都是“功能”,因为领域模型必须能
支持在《软件需求规格说明书》中规定的“现在的功能”,还应该支
持随着业务发展而出现的“未来的功能”。这两种功能,就是驱动领
域建模的因素,以及评审领域模型的依据。
更多内容,请阅读本书讲领域建模的章:第7章,领域建模。
4.2.3 确定关键需求
架构面前所有需求一律平等?不可能。
关键需求决定了架构的大方向。图4-9显示了确定关键需求工作的
位置。图4-8 领域建模的“输入”和“输出”
图4-9 确定关键需求的“位置”
具体而言,为了确定“关键功能”,一要关注“功能需求”,二
要研究“约束需求”;为了确定“关键质量”,一要关注“质量需
求”,二要研究“约束需求”。如图4-10所示。图4-10 确定关键需求的“输入”、“技能项”和“输出”
大系统架构与小系统架构的设计为什么不同?你的系统架构与别
人的系统架构设计为什么不同?……探究架构设计的整个过程,“关
键需求的确定”这一步是“分水岭”。
更多内容,请阅读本书讲确定关键需求的章:第8章,确定关键需
求。
4.2.4 概念架构设计
概念架构是高层架构成果的核心,框定了架构大方向,是甲方规
划、乙方投标的评定关键。如图4-11所示。图4-11 概念架构设计的“位置”
本书给出的定义,所谓概念架构,是直指系统目标的设计思想、重大选择。“直指目标”说的是输入,“设计思想和重大选择”说的
是输出。如图4-12所示。
图4-12 概念架构设计的“输入”、“技能项”和“输出”
· 概念架构设计要“直指”的、以之为输入的,就是“关键需
求”。
· 针对不同需求(功能或者质量),需要运用不同“技能项”,鲁棒图建模、目标-场景-决策表,非常实用。· 概念架构设计的“输出”是“1个决定、4个选择”:
1)决定如何划分顶级子系统;
2)架构风格选型;
3)开发技术选型;
4)二次开发技术选型;
5)集成技术选型。
更多内容,请阅读本书讲概念架构设计的章:第9章,概念架构设
计。
4.2.5 细化架构设计
细化架构和概念架构的关键区别之一是:概念架构没有设计到
“模块+接口”一级,而细化架构必须关注“模块+接口”。图4-13所
示为细化架构设计的“位置”。
图4-13 细化架构设计的“位置”
众所周知,架构设计涉及的方面很广(模块切分、持久化格式、并行并发等都得管),架构设计师得是通才(要掌握的技能项较
多)。对此,细化架构设计这一步体现得最充分,图 4-14 列出了细
化架构设计的5个设计视图、15个设计任务。题4-14 细化架构设计的“技能项”——15个设计任务
再关注上游对细化架构设计的影响、支持。细化架构设计的输入
既来自“需求成果”层面、也来自“高层架构”层面,如图4-15所
示。
· 细化架构要为“需求”而设计。关键对比:概念架构设计的输
入是“关键需求”、而不是泛泛的所有“需求”。
· 细化架构要在“概念架构”的设计思想下进行。
· “领域模型”,一方面影响着“逻辑架构视图”的“领域模型
设计”,另一方面影响着“数据架构视图”的“存储格式设计”。图4-15 细化架构设计的“输入”和“输出”
更多内容,请阅读本书讲细化架构设计的章:
· 第10章,细化架构设计。
· 第12章,粗粒度“功能模块”划分。
· 第13章,如何分层。
· 第14章,用例驱动的模块划分过程。
· 第15章,模块划分的4步骤方法——运用层、模块、功能模
块、用例驱动。
4.2.6 架构验证
如有必要,需要进行架构验证。如图4-16所示。
架构验证的输出成果是“架构原型”。和一般的开发不同,架构
原型的开发不是要完美地、无 Bug 地实现功能,而是在“细化架构”
的总体指导下,仅把存在“风险”的那些设计尽早开发出来,然后通
过执行测试等手段判断“风险”是否解决,如图4-17所示。
更多内容,请阅读本书讲架构验证的章:第11章,架构验证。图4-16 架构验证的“位置”
图4-17 架构验证的“输入”和“输出”第5章 需求分析
对于需求分析员而言,真正的专业主义是基于业务利益(解决问
题、创造机会、提高管控力等)的沟通。
——徐锋,《软件需求最佳实践》
当前业界,大多数架构师都认同“需求决定架构”,但对需求
“如何决定”架构还知之不深。……不同需求影响架构的不同原理,才是架构设计思维的基础。
——温昱,《一线架构师实践指南》
一个程序员,在向架构师转型的道路上,一定“绕”不过软件需
求的问题。本章立足软件开发人员的视角,逐次讨论:
· 需求怎么来的?(需求开发=愿景分析+需求分析)
· 如何判断掌握的需求全不全?(功能、质量、约束三类需求都
不能漏)
· 从需求向设计转化的关键思维是什么?(功能、质量、约束影
响架构的不同原理是核心)
5.1 需求开发(上)——愿景分析
我们从“整体过程”入手,然后聚焦讨论“愿景”和“愿景分
析”。
5.1.1 从概念化阶段说起
图 5-1 所示为软件研发与交付过程总图,包含概念化阶段、需求
分析阶段、架构设计阶段、并行开发与测试阶段、验收与交付阶段,共5个阶段。图5-1 软件研发与交付过程总图
随着研发类型的不同(项目、产品、或解决方案),概念化阶段
包含的工作重点有所不同,但主要内容都包括:
· 愿景分析。
· 风险评估。
· 可行性分析。
· 项目进度和成本的粗略预估。
下面聚焦讨论“愿景”。
5.1.2 愿景愿景分析,要解决项目、产品或解决方案的起源问题。所谓明确
愿景,就是针对系统目标、主要特性、功能范围和成功要素等进行构
思并达成一致。
对定制开发的软件项目来说,愿景分析可由需方或者软件供应商
来组织,一般建议由需方高层领导牵头,愿景分析过程中需方人员也
必须全程积极参与。而对产品型的软件公司来说,往往是产品管理部
门根据市场部门的要求,进行愿景分析、定义产品所要提供的业务功
能。无论上述哪种情况,愿景分析都应阐明业务需求、描述需求产生
的背景和理由等。
愿景分析最重要的工作成果是《愿景与范围文档》。记得有一位
大师,当被问及“如果软件开发中只能有一份文档,应当是哪一份”
时,他毫不犹豫地回答说是《愿景文档》。由此可见《愿景与范围文
档》的重要性。
典型的《愿景与范围文档》包括下列内容:
1.业务需求
a) 背景
b) 业务机遇
c) 业务目标
d) 客户或市场需求
e) 提供给客户的价值
f) 业务风险
2.项目愿景的解决方案
a) 项目愿景陈述
b) 主要特征
c) 假设和依赖环境
3.范围和局限性
a) 首次发布的范围
b) 随后发布的范围
c) 局限性和专用性4.业务环境
a) 客户概貌
b) 项目的优先级
5.产品成功的因素
在此有必要指出,你可能在不同类型的软件企业工作(例如项目
型公司、产品型公司、外包型公司、服务型公司等),于是,由于偏
重内容有所不同,你所在的企业对《愿景与范围文档》其实有着不同
的叫法。例如:
· 有 的 产 品 型 公 司 , 称 为 《 市 场 需 求 文 档 》 ( Market
Requirements Document,MRD);
· 有的产品型公司,称为《产品需求文档》(Product
Requirements Document,PRD);
· 有的以做项目为主的公司,称为《项目立项书》。
5.1.3 上下文图
在《愿景与范围文档》中,上下文图(Context Diagram)扮演着
重要角色。
上下文图是一种“辅助说明”需求范围(Scope)的方式,它清晰
地描述了待开发系统与周围所有事物之间的界限与联系。上下文图可
以由市场部门绘制(画法相对随意例如利用PowerPoint),也可以由
架构师来绘制(推荐UML用例图的顶级视图)。
下面我们举例,看到实际的上下文图,能让我们更“实在”地理
解什么是一个系统的愿景。
【案例1】银行“综合前置系统”的上下文图
例如,你所在的银行开发中心,要研制综合前置系统。
图 5-2 展示了银行综合前置系统的上下文图,从一个方面“描
绘”了愿景。首先,我们看到要研发的综合前置系统在上下文图中还
是个黑盒子,里面的组成并不清楚,否则就不是上下文图了。其次,我们通过上下文图理清了和综合前置黑盒子有关联的4类系统,分别是
主机、外挂、第三方、渠道。图5-2 银行综合前置系统的上下文图
【对比1】总体架构的物理视图(不是上下文图,也不是“综
合前置系统”的)
上下文图之所以非常有用,关键在于它以“待研发的系统”为中
心。对此,Kossiakoff 有如此论述:
待研发系统位于上下文图的中心,所有和待研发系统有关联关系
的系统、环境和活动围绕在它的周围。但是,上下文图不提供系统内
部结构的任何信息。上下文图的目的是通过明确系统相关的外部因素
和事件,促进更完整地识别系统需求和约束(pictures the sy stem
at the cent er,with no deta ils of its interior structure,surrounded by all its interacting systems,envir onment and
ac tivities.The obj ective of a sy stem cont ext diagram is
to f ocus att ention on external fac tors and ev ents thatshoul d be consid ered i n developing a complete set of
system requirements and constraints)。
本书将上下文图的要点归纳为两点:
· 内容原则 。关注本系统,以及和本系统有关联的因素,但不
关注本系统内部——既不关注内部功能,也不关注内部结构。
· 形式原则 。明确标识出要研发的是什么系统,保持它为黑
盒,将它画在上下文图的中央位置,其他相关因素环绕周围。
回顾图 5-2,它就是以“综合前置系统”为中心的上下文图,满
足上述“内容原则”和“形式原则”。
对比图5-3:
· 内容 。该图是整个“银行核心系统”,而不是“综合前
置”。“综合前置”只是整个“银行核心系统”的一部分。
· 形式 。该图不是以“中心+四周”形式组织的。
· 结论 。该图不是“综合前置系统”的上下文图,而是银行核
心系统的总体架构图(物理视图)。
【对比2】银行“综合前置系统”的架构图(不是上下文图)
作为对比,再看图 5-4,它是综合前置系统的架构图(属于设
计),而不是上下文图(说明需求范围)。图中表达的架构级设计决
策包含:
· 首先,中心前置业务平台和分行前置业务平台,是综合前置的
核心,分别部署在总行数据中心和每家分行的运行中心。
· 为了支持网上银行,综合前置中包含网银接入平台,在总行一
级部署、连接到中心前置业务平台。
· 和网上银行的“由总行一级统一支持”方式不同,综合前置为
了支持电话银行而包含了电话接入前置平台,在每家分行一级部署、连接到分行前置业务平台。
·……综合前置还包括核心系统的连接、自助设备接入、RA前置
机等设计。
· 综合前置与人民银行系统互联、还与代理商户互联,具体设计
策略有何不同吗?综合前置的分行前置业务平台,负责和当地人民银行,以及当地
代理商户互联;
如果不是当地代理商户、而是中心级代理商户,应直接和综合前
置的中心前置业务平台互联;
人民银行总中心,直接和综合前置的中心前置业务平台互联。图5-3 银行核心系统的总体架构图(物理视图)
(图片来源:http:www.cbinews.comsolutionnews2187.html)【案例2】对讲机软件:上下文图vs.用例图
再例如,你是一个嵌入式软件架构师,你要负责的是对讲机内的
软件。
图 5-5 分别展示了对讲机的上下文图,以及用例图(用于对
比)。图中的上下文图采用了“用例图风格”来画,现在用例技术很
流行所以笔者推荐这种画法,但注意它并不等同于“用例图”。区别
的关键是,用例图刻画了“对讲机”提供的各种功能,而“用例图风
格”的上下文图没有刻画功能。正如笔者前文所述的上下文图“内容
原则”:上下文图“不关注本系统内部——既不关注内部功能,也不
关注内部结构”。
图5-4 银行综合前置系统的基本架构图图5-5 对讲机:上下文图vs.用例图
总之,上下文图可以明确:1)哪个系统是待研发的软件系统;
2)哪些方面在软件系统之外;3)谁使用该系统;4)此软件系统需要
和哪些相关软件系统进行交互。
5.1.4 愿景分析实践要领
愿景分析,换个角度讲就是我们常说的需求调研(愿景分析的说
法重目标,需求调研的说法重活动)。为了便于掌握实践要领,本书
推荐这样一个务实的公式,如图5-6所示:
愿景=业务目标+范围+Feature+上下文图图5-6 愿景=业务目标+范围+Feature+上下文图
范围(Scope)、Feature、上下文图是刻画高层需求的“三剑
客”,常用,好用!图 5-7 再次描述了这三种技术的定位,以及它们
和系统业务目标的关系。
图5-7 业务目标、范围、Feature、上下文图的关系
5.2 需求开发(下)——需求分析什么是软件需求?简单地说,软件需求就是“这个软件到底要为
用户做什么”。
IEEE的软件工程标准术语表将需求定义为:
1.用户所需的解决某个问题或达到某个目标所要具备的条件或能
力。
2.系统或系统组件为符合合同、标准、规范或其他正式文档而必
须满足的条件或必须具备的能力。
3.上述第一项或第二项中定义的条件和能力的文档表述。
而RUP是这样定义需求的:
需求描述了系统必须满足的情况或提供的能力,它就可以是直接
来自客户需要,也可以来自合同、标准、规范或其他有正规约束力的
文档(A require ment describes a condition or either derived
directly fro m user needs,or stated in a contract,standar
d,specification,or other formally imposed document.)。
架构师必须懂需求吗?是的。
架构师岗位本身,并不负责需求分析,但对需求分析的工作过程
一定要了解。
5.2.1 需求捕获vs.需求分析vs.系统分析
从软件过程全局看,需求分析是一个承上启下的阶段——“上
承”愿景,“下接”设计。上游,进行愿景分析、研究可行性、输出
《愿景与范围文档》,需求分析要进一步完善和细化软件需求。后
续,要进行的设计活动,以需求分析活动定义的功能需求、质量属性
需求以及约束性需求等为基本参考。
我们经常说的“需求分析”工作、经常被称为的“需求分析员”
岗位,其背后其实涉及的活动包含:
· 需求捕获。
· 需求分析。
· 系统分析。需求捕获是获取知识的过程,知识从无到有、从少到多。需求采
集者必须理解用户所从事的工作,并且了解用户和客户希望软件系统
在哪些方面帮助他们。
需求分析是挖掘和整理知识的过程,它在已掌握知识的基础上进
行。毕竟,初步捕获到的需求信息往往处于不同层次,也有一些主观
甚至不正确的信息。而经过必要的需求分析工作之后,需求会更加系
统、更加有条理、更加全面。
那么系统分析呢?如果说,需求分析致力于搞清楚软件系统要
“做什么”的话,那么系统分析已经开始涉及“怎么做”的问题了。
《系统分析》一书中写道:
简单地说,系统分析的意义如下:“系统分析是针对系统所要面
临的问题,搜集相关的资料,以了解产生问题的原因所在,进而提出
解决问题的方法与可行的逻辑方案,以满足系统的需求,实现预定的
目标。”
【实际问题1】将需求捕获和需求分析视为两个阶段,这是错
误的
需求捕获、需求分析以及系统分析是相互伴随、交叉进行的(如
图5-8所示):
· 需求工作伊始,更多进行需求捕获,需求分析工作偏少;
· 随着掌握的需求信息越来越多,对需求的分析才可能越来越
多;
· 世界不是“问题—解决方案”这么简单的模型,是“问题—解
决方案—衍生问题—解决方案—……”才现实——上一级的解决方案
对下一级就意味着“待解决的问题”。于是,需求分析连带出更多系
统分析的工作非常正常。图5-8 需求捕获、需求分析与系统分析
将需求捕获和需求分析视为两个阶段,这是错误的。例如,图 5-
9 来自某企业的《需求开发过程》规范,就将“获取需求”和“分析
需求”定义成了两个阶段。这种“捕获得到全部需求,之后再集中进
行分析”的做法不务实、效果差、容易引起大量需求变更。
图5-9 错误的需求开发过程(来自某企业的《需求开发过程》规范)
【实际问题2】需求分析与系统分析混淆实践中,需求分析和系统分析常被混淆。一位技术经理,就不无
困惑地问过我:“我们公司的需求分析员提交的《系统需求文档》里
面有一节叫‘系统分析’,但内容都是系统设计的,好像明显在和我
这个架构师‘争功’,真不知该怎么办?”
为了不再混淆这两者,应明确:
· 需求分析,是搞清楚系统“做什么”。
· 系统分析,关注系统“怎么做”。更直白地说,系统分析 ≈
初步的高层设计。
· 很多开发者对OOA心存困惑。其实,OOA是一种“系统分析”技
能,对很多“需求分析”内容并不涵盖。认为掌握了 OOA 就能做需求
分析了,结果会“死得很难看”。
对此,邵维忠教授和杨芙清院士在《面向对象的系统设计》中有
过精彩论述:
用“做什么”和“怎么做”来区分分析与设计,是从结构化方法
沿袭过来的一种观点。但即使在结构化方法中这种说法也很勉强……
在“做什么”和“怎么做”的问题上为什么会出现上述矛盾?究
其根源,在于人们对软件工程中“分析”这个术语的含义有着不同的
理解——有时把它作为需求分析(Requirements Analy sis)的简
称,有时是指系统分析(Systems An alysis),有时则作为需求分析
和系统分析的总称。
需求分析是软件工程学中的经典的术语之一,名副其实的含义应
是对用户需求进行分析,旨在产生一份明确、规范的需求定义。从这
个意义上讲,“分析是解决做什么而不是解决怎么做的问题”是无可
挑剔的。
但迄今为止人们所提出的各种分析方法(包括结构化分析和面向
对象分析)中,真正属于需求分析的内容所占的分量并不太大;更多
的内容是给出一种系统建模方法(包括一种表示法和相应的建模过程
指导),告诉分析员如何建立一个能够满足(由需求定义所描述的)
用户需求的系统模型。分析员大量的工作是对系统的应用领域进行调
查和研究并抽象地表示这个系统。确切地讲,这些工作应该叫做系统分析,而不是需求分析。它既是对“做什么”问题的进一步明确,也
在相当程度上涉及“怎么做”的问题。
忽略分析、需求分析和系统分析这些术语的不同含义,并在讨论
中将它们随意替换,是造成上述矛盾的根源。
5.2.2 需求捕获及成果
典型的需求捕获的工作成果是一摞“需求采集卡”(如表 5-1 所
示),其中记录了需求类型、需求描述、需求背景、需求提出者和需
求记录者等对进一步的需求分析非常有用的信息。
表5-1 需求采集卡
5.2.3 需求分析及成果
用例技术要登场了。
通过需求采集活动,我们捕获到了大量“原始需求”,而需求分
析则对采集到的原始需求进行分析、整理、辨别和归纳,最终形成系
统的、明确的软件需求。
需求分析应交付一份明确的、规范的需求定义——《软件需求规
格说明书》(Software Requirements Specification,SRS)。
《SRS》精确地阐述了一个软件系统必须提供的功能、必须达到的质量
属性指标,以及它必须遵守的约束。其中,当前最常用的是用例(Use
Cas e)技术,用例图“立足整个系统”刻画系统能为外部用户或系统
提供的服务,用例规约“聚焦每个功能”刻画系统应提供的具体行为。因为《SRS》应尽可能完整地描述各种条件下的系统行为,所以重
点用例的用例规约要将多种可能的“意外情况”描述出来。
续表5.2.4 系统分析及成果
对于不同的系统分析方法,其工作成果差异很大。通过结构化分
析方法得到的最重要的工作成果是数据流图,而面向对象的系统分析
方法得到的工作成果主要是分析类图、鲁棒图、序列图等——其中分
析类图描述设计的静态方面,而鲁棒图和序列图描述设计的动态方
面。
5.3 掌握的需求全不全
架构师需要全面了解需求吗?是的。观念是行为的“向导”,有
怎样的观念存在,就有怎样的行为方式产生——“观念突破”的意义
就在于此。
程序员向架构师转型时,需求列表这种观念需要突破:
· 作为程序员 ,“你”经常目睹下面这一切:项目经理打开
Excel 表格,根据“Feature List”分配工作,一个程序员负责实现
几项,倍儿清楚。如此种种,使“你”确信需求就是列表(List)。
· 作为从程序员成功转型的架构师 ,“你”会关注功能需求、质量、约束等各种需求类别,更不希望因为没有“需求大局观”而造成需求遗漏。这时,需求列表对“你”架构设计工作的支持已经捉襟
见肘。
5.3.1 二维需求观与ADMEMS矩阵
突破“需求列表”思维,应以“二维需求观”来看待需求(如图
5-10所示)。
首先,需求是分层次的 。本质上,我们是根据“不同层次的涉
众提出需求所站的不同立场”,将需求划分为三个层次。其实,为了
便于需求跟踪(核心是跟踪需求来源),我们也必然要这么做。
· 组织级需求 。包含客户或出资者要达到的业务目标、预期投
资、工期要求,以及要符合哪些标准、对哪些遗留系统进行整合等约
束条件。
· 用户级需求 。用户使用系统来辅助完成哪些工作?对质量有
何要求?用户群及所处的使用环境方面有何特殊要求?
· 开发级需求 。开发人员需要实现什么?开发期间、维护期间
有何质量考虑?开发团队的哪些情况会反过来影响架构?
图5-10 二维需求观
其次,需求还必须从不同方面进行考虑 。实践一再表明,忽视
质量属性和约束性需求,常常导致架构设计最终失败。例如,一个网上书店系统:
· “浏览书目”、“下订单”、“跟踪订单状态”以及“为书籍
打分”等,属功能需求。
· 系统应当有良好的“互操作性”和“安全性”,这是质量属性
需求。
· 系统“必须运行于Linux平台之上”,则属于约束性需求之
列。
也就是说,从“直接目标还是间接限制”的角度把需求分为三
类。
· 功能需求:更多体现各级直接目标要求。
· 质量属性:运行期质量+开发期质量。
· 约束需求:业务环境因素+使用环境因素+构建环境因素+技术
环境因素。
作为设计人员,经常问的一个问题是:我掌握的需求全不全,有
没有遗漏?
《一线架构师实践指南》一书提出的 ADMEMS 矩阵(又称“需求
层次-需求方面矩阵”)可以作为需求梳理和需求评审的工具,以一种
直观易行的“Checklist思维”帮助设计人员全面梳理和评价需求,如
图5-11所示。
5.3.2 功能
功能需求是我们最熟悉的一类需求,它描述系统“应该做什
么”。如果采用比较简单的方式,可以在《软件需求规格说明书》中
逐个列举每个功能项、进行简要说明,如表 5-2所示。图5-11 ADMEMS矩阵(需求层次—需求方面矩阵)
表5-2 功能描述示例(一卡通系统功能描述的一小部分)
如果采用比较正规的方式,可以在《软件需求规格说明书》中将
每项功能的用户类、用户输入或系统外激励、系统动作(本项和前一
项相当于用例规约的主事件流)、业务规则、例外及相应处理(本项相当于用例规约的备选事件流)、特殊需求或限定、相关功能、注释
和说明等内容进行展开说明,如表5-3所示。
表5-3 功能描述示例(CRM的修改客户联系人资料功能)
续表
5.3.3 质量
下面重点讨论非功能需求中的质量属性需求。
如何给众多质量属性分类,这是一个问题。McCall 等人于 1977
年提出的软件质量属性的分类模型,影响非常广泛。如图 5-12 所示,它将软件的质量属性划分为三大类:产品操作、产品修改、产品
改型。
图5-12 McCall等人提出的软件质量属性的分类模型
该分类方法相当经典,但似乎缺少了“产品开发”类的质量属性
——诸如易理解性、可扩展性和可重用性等。另一方面,我们也发现
产品开发、产品修改和产品改型这三类质量属性有重叠(如易理解性
和可扩展性对开发和维护都很重要,再如对产品改型很关键的可重用
性也同样影响着产品开发)。因此,考虑到被广泛认同的迭代式开发
所暗示的增量交付使开发、修改和维护之间的界限不再像以前那么明
显,所以本书认为有充分的理由将产品开发、产品修改和产品改型这
三类质量属性合并为一类。
本书推荐将软件质量属性划分为运行期质量属性和开发期质量属
性两大类(如表 5-4 所示):
· 开发期质量属性其实包含了和软件开发、维护和移植这三类活
动相关的所有质量属性,可以说这里的“开发”是相当广义的;
· 开发期质量属性是开发人员、开发管理人员和维护人员都非常
关心的,对最终用户而言,这些质量属性只是间接地促进用户需求的
满足;· 运行期质量属性是软件系统在运行期间,最终用户可以直接感
受到的一类属性,这些质量属性直接影响着用户对软件产品的满意
度。
表5-4 推荐的软件质量属性分类方式
运行期质量属性需求是一类非常重要的非功能需求,对客户满意
度非常关键,下面一一进行说明。
性能 (Performance)。性能是指软件系统及时提供相应服务的
能力。具体而言,性能包括速度、吞吐量和持续高速性三方面的要
求:
· 吞吐量通过单位时间处理的交易数来度量;
· 速度往往通过平均响应时间来度量;
· 而持续高速性是指保持高速处理速度的能力。
持续高速性和实时系统有关,实时系统有“硬实时”和“软实
时”之分,其中硬实时系统对每次系统响应时间都有严格要求,如果
不能满足要求,后果将是致命的,所以把性能笼统地说成“进行典型
操作所需的时间”显然忽视了实时系统性能的内涵。
下面值得说明效率(Efficiency)和性能的关系:它们反映了同
一问题的“表”、“里”两面,性能为“表”,效率为“里”,如图
5-13 所示。所谓效率,是指软件系统对各种资源(CPU、内存、硬盘
存储、硬盘IO、网络带宽等)的使用效率。安全性 (Security)。安全性指软件系统同时兼顾向合法用户提
供服务,以及阻止非授权使用的能力。高安全性意味着“同时兼
顾”,这是因为有些攻击的目的是使软件系统拒绝向合法用户提供服
务,而不是非法访问。
易用性 (Usability)。不少文献也称之为可用性,但为了避免
和持续可用性(Availability)混淆,本书采用非常流行的“易用
性”的叫法。指软件系统易于使用的程度。
图5-13 性能和效率的关系
持续可用性 (Availability)。不少文献也称之为可用性,但为
了避免和易用性(Usability)混淆,本书采用“持续可用性”的叫
法。持续可用性指系统长时间无故障运行的能力。可伸缩性 (Scalability)。可伸缩性指当用户数和数据量增加
时,软件系统维持高服务质量的能力。例如当业务量较小时,软件系
统运行在一台服务器上,当业务量增大时,可以通过增加服务器或增
加单台服务器上所运行软件系统的个数来提高性能,而无需对软件系
统本身进行编程级的修改。
互操作性 (Interoperability)。可操作性指本软件系统与其他
系统交换数据和相互调用服务的难易程度。
可靠性 (Reliability)。软件系统在一定的时间内无故障运行
的能力。
鲁棒性 (Robustness)。鲁棒性也称健壮性、容错性。鲁棒性是
指软件系统在以下情况下仍能够正常运行的能力:用户进行了非法操
作;相连的软硬件系统发生了故障,以及其他非正常情况。
而开发期质量属性则随着软件系统规模的日益增长,显得越来越
重要了,下面一一说明之。
易理解性 (Understandability)。尤指设计被开发人员理解的
难易程度。
可扩展性 (Extensibility)。可扩展性是指为适应新需求或需
求的变化为软件增加功能的能力。我们在实际工作中,经常将可扩展
性称为灵活性。
可重用性 (Reusability)。可重用性是指重用软件系统或其一
部分能力的难易程度。
可测试性 (Testability)。可测试性是指对软件测试以证明其
满足需求规约的难易程度。在实际工作中主要指进行单元测试、插桩
测试等的难易程度。
可维护性 (Maintainability)。可维护性是指为了达到下列三
种目的之一而定位修改点并实施修改的难易程度:修改Bug;增加功
能;提高质量属性。
可移植性 (Portability)。可移植性是指将软件系统从一个运
行环境转移到另一个不同的运行环境的难易程度。
务实地,我们可以将运行期质量属性和功能性一起视为“软件的
外部质量”,而将开发期质量属性视为“软件的内部质量”。无疑,软件的内部质量制约着软件的外部质量;在软件开发管理本身已经十
分复杂的今天,想使内部质量很差的软件具有良好的外部质量几乎是
不可能的。同时,随着商业环境变化的加剧,很多企业软件出现了
“建成即废弃”的尴尬情况。于是,软件系统的内部品质越来越受到
重视,通过强化软件系统的可扩展性、可重用性、易理解性等开发期
质量属性,可以使软件有更多被改变、被重用的空间。
5.3.4 约束
业界对约束一直不够重视,例如《UML 和模式应用(第 2 版)》
一书对约束的理解就太简单了:
约束 不是行为,是设计或项目的某些限制条件。这些限制条件也
属于需求,但通常被称为“约束”来强调其限制性。例如:
· 必须使用Oracle(我们硬件签署过使用许可证了);
· 必须在Linux上运行(成本低)。
笔者在《一线架构师实践指南》一书中做了梳理总结:
约束需求=业务环境因素+使用环境因素+构建环境因素+技术环境
因素。
第一,业务环境因素(来自客户或出资方的约束性需求)。
· 架构师必须充分考虑客户对上线时间的要求、预算限制、以及
集成需要等非功能需求。
· 客户所处的业务领域为哪些?有什么业务规则和业务限制?
· 是否需要关注相应的法律法规、专利限制?
·……
第二,使用环境因素(来自用户的约束性需求)。
· 软件将提供给何阶层用户?
· 用户的年龄段及使用偏好是哪些?
· 用户是否遍及多个国家?
· 使用期间的环境有电磁干扰、车船移动等因素吗?
·……第三,构建环境因素(来自开发者和升级维护人员的约束性需
求)。
· 开发团队的技术水平如果有限(有些软件企业甚至希望通过招
聘便宜的程序员来降低成本)、磨合程度不高、分布在不同城市,会
有何影响?
· 开发管理方面、源代码保密方面,是否需要顾及?
·……
第四,技术环境因素(也不能遗忘,业界当前技术环境本身也是
约束性需求)。
· 技术平台、中间件、编程语言等的流行度、认同度、优缺点
等。
· 技术发展的趋势如何?
·……
架构师应当直接或间接(通过需求分析员)地了解和掌握上述需
求和约束,并深刻理解它们对架构的影响,只有这样才能设计出合适
的软件架构。例如,如果客户是一家小型超市,软件和硬件采购的预
算都很有限,那么你就不宜采用依赖太多昂贵中间件的软件架构设计
方案。
5.4 从需求向设计转化的“密码”
不重视需求,设计必死。对需求的重视停留在口头,却不能体现
到设计中,设计也会死。
我们都知道,整个设计“过程”中的关键一环是从需求向设计的
“转化”或“过渡”。少了这一环,“重视需求”就是一句口号,需
求和设计就是“两层皮”,设计就沦为了“拍脑袋”。
怎么办?
建议每一个架构师,都要精通“功能、质量、约束影响架构的不
同原理”——这,是从需求向设计转化的“密码”。
5.4.1 “理性设计”还是“拍脑袋”开发设计人员都知道,需求决定架构。看了本章前述内容后我们
又知道,软件需求=功能+质量+约束(如图5-14所示)。
图5-14 软件需求的类型
功能、质量、约束这三种需求影响架构的不同原理,是从需求向
设计的“转化的密码”和“过渡的钥匙”。要进行“理性设计”,这
是基础。表 5-5 归纳了不同需求如何以不同原理影响架构设计的。
表5-5 不同需求影响架构的原理不同5.4.2 功能:职责协作链
任何一项功能都是由一条特定的“职责协作链”完成的,如图 5-
15 所示。作为完整的软件系统,它在支持每一个具体功能时,都必然
涉及软件不同“部分”之间的相互配合。系统的控制权在这些不同的
“部分”之间来回传递,形成一条“职责协作链”,可以完成非常复
杂的功能。图5-15 功能影响架构的基本原理:职责协作链
反过来,在设计架构时,就是要通过为功能规划职责协作链来发
现职责,再将职责分配到子系统等软件单元中去,后续就可以定义接
口,确定协作方式了……
5.4.3 质量:完善驱动力
质量,是完善架构设计的驱动力,不考虑质量的系统是无法走出
实验室的。如图 5-16 所示,基于中间设计成果进一步质疑是其中基
本的“思维方式”。例如,如果只考虑功能,“页面缓存”的设计就
永远不会被引入,它是质疑性能、调整设计的结果。图5-16 质量影响架构的基本原理:进一步质疑
必须注意:
第一,抛开功能、单依据质量要求,是不可能设计出架构的。打
个赌:我有个 2000 万的系统想请你承接,不告诉你业务领域和功能
要求,你能设计出一个高性能的架构给我评审吗?
第二,实际的设计过程是,质量是一种评价、一种针对“已然存
在”的设计的评价,我们基于当前的架构设计中间成果,进一步考虑
具体质量要求,对设计中间成果进行细化、调整、甚至推倒重来……
5.4.4 约束:设计并不自由
设计并不自由。对于架构设计而言,来自方方面面的约束性需求
中潜藏了大量风险因素。所以,有经验的架构师都懂得主动分析约束影响、识别架构影响因素,以便在架构设计中引入相应决策予以应
对。
我们以 ADMEMS 矩阵为“思维画布”,考虑一个银行储蓄系统可
能涉及的约束需求(如图5-17所示),是如何以不同的具体方式影响
架构设计的:
· 直接制约设计决策的约束 。例如,“系统运行于 UNIX 平台
之上”作为一条约束,架构师直接遵守即可。
· 转化为功能需求的约束 。例如,“本银行系统必须严格执行
人民银行统一规定的利率”是一条约束,但分析后发现,正是它引出
了一条功能需求,即必须提供调整利率设置的实用功能。
· 转化为质量属性需求的约束 。例如,有经验的系统分析员发
现了一条重要约束:“任职于各储蓄所和分理处的柜员,计算机水平
普遍不高”。由此,未来的软件系统必须具有很高的易用性(否则不
会用)和鲁棒性(否则可能把系统搞瘫痪了)就是非常必要的。
图5-17 分析约束影响示例(银行储蓄系统)
5.5 实际应用(3)——PM Suite贯穿案例之需求分析
知识点、技能项都讲了不少,下面实际应用到PM Suite 贯穿案
例,对PM Suite 系统进行需求分析。需求分析主线中所包含的关键步骤,可以概括为“三横两纵”,如图5-18所示。
· 三横。
确定系统目标。
研究高层需求。
建立用例模型。
· 两纵。
需求沟通、需求启发、需求验证。
确定非功能需求。
所谓“纵”,指的是实践中需要持续不断地进行。所谓“横”,则是有先后之分的。“确定系统目标→研究高层需求→建立用例模
型”这三步,后一步需要前一步的工作成果作为输入,如图5-19所
示。
图5-18 需求分析主线的“三横两纵”图5-19 需求分析主线的“三横”
5.5.1 PM Suite案例背景介绍
PM S uite,是一个分布式的组织级项目管理系统,是本书用做贯
穿案例的一个虚拟的软件产品。
PM Suite覆盖企业的单项目管理、项目群、项目组合管理,以及
配套的辅助管理。它包含丰富的功能,涉及决策层、管理层、实施层
等众多功能点,帮助组织统管项目实施层、管理层、决策层,有助于
企业固化项目管理流程和体系。
PM Suite 互操作性强,能与其他不同知名产品(例如配置管理、Bug管理)整合,从而将组织项目管理体系连成一个整体,改善项目管
理的效能。
5.5.2 第1步:明确系统目标一个客户组织,为什么要采购PM Suite作为项目管理平台呢?
PM Suite 作为一个软件产品要被开发,要拨款立项,我们首先要
搞清楚一个问题——即确定系统的建设目标。经过了解情况,梳理分
析,我们确定了 PM Suite 要达到的四大业务目标(如表5-6所示)。
表5-6 整个PM Suite贯穿案例的第1 个工作成果
PM Suite 产品的“根”就在这里:系统的业务目标。我们要把业
务目标写入《愿景文档》,成为《愿景文档》内容的关键部分。若是
采用敏捷软件开发方式,也必须重视业务目标,可以采用“目标列
表”的形式明确记录它。
5.5.3 第2步:范围+Feature+上下文图
现在,我们已经明确了 PM Suite 的 4 个业务目标。接下来,是
不是就可以进行用例建模了呢?
如果是小系统,接下来就可以用例建模了;但如果是大系统,或
是业务复杂的系统,或是解决方案,明智的做法是
在确定业务目标之后、进行用例建模之前,通过“范围
+Feature+上下文图”来进一步明确高层需求。
【技能1】高层需求之确定范围
实际工作当中,描述需求范围经常采用的方式有如下几种:1)文
字描述法;2)业务域列举法;3)框图法(平实风格);4)框图法
(商务风格)。对于 PM Suit e 系统,我们经由对“组织级项目管理”涉及管理
内容的分析,确定它的需求范围(Scope)涵盖4块主要内容。如果采
用“业务域列举”法,可以这样描述:
· 项目基础管理。
· 单项目管理。
· 项目群管理。
· 项目组合管理。
如果换用“框图法(平实风格)”,可以用图5-20来进行描述。
图5-20 PM Suite高层需求之需求范围
如果你是为公司写市场材料,画图当然要更“炫”一些,此时
“框图法(商务风格)”是不二之选。例如,图 5-21 就采用了商务
风格的框图法,该图来自维普公司(http:www.vpsoft.cn)的市场
材料,描述的就是相关产品的“需求范围”。图5-21 采用“框图法(商务风格)”描述需求范围
(图片来源:http:www.vpsoft.cn)
【解惑】需求范围框图 ≠ 架构图
在笔者为不少企业提供架构培训的课堂间隙,都有学员提出类似
“需求范围框图是不是架构图”的问题。最典型的是有一次,一位学
员拿着一个软件厂商的市场彩页给我看,说:“温老师,你看这个材
料,上面可是把这个图叫‘架构图’的呀……”
其实这样的图(如图 5-22 所示),最精确的叫法就是“需求范
围框图”,这才是揭示此图本质的称呼。图5-22 “需求范围框图”的例子
【技能2】高层需求之定义Feature
Feature的应用,在实际工作中比较灵活,但也有规律。归纳而
言:
· 内容。
列举系统大致支持哪些功能组(粒度:大)。
例如:办公软件“公文交换”Feature,其实是功能组。
强调说明某些最有特色的功能项(粒度:中)。
例如:办公软件“支持公文下发、上报和水平发送等多种方式”
Feature,其实是列举功能项。
点出功能项的更细节优势(粒度:小)。
例如:办公软件“在 Word 中编辑的公文可直接在 Word 中发起
上报,快捷高效”Feature,其实是说明一个功能项(公文上报)的具
体卖点。
技术特色、其他特色的强调。
例如:办公软件“和微软 Office、即时通信软件无缝整合”及
“多浏览器支持”等Feature,就是在讲技术特色。· 描述方式。
文字描述法。
框图法。
功能树法。
现在,我们继续PM Suite 贯穿案例的需求分析。既然前面已明确
了“需求范围”,下面我们问自己:在此“需求范围”内为了达到
“业务目标”需要具有哪些Feature才行呢?
图5-23展示了PM Suite 案例的从业务目标到特性列表的思维过
程。例如,为了实现“统一平台”的目标,一方面要“内置著名软件
工具的集成支持”,另一方面要“方便通过二次开发集成新的工
具”,看来将来对Web S ervice或著名消息中间件等技术的支持在所
难免。再例如,为了实现提高“组织级项目管控力”的目标,“覆盖
和打通组织级与项目级项目管理”这一Feature就必不可少。图5-23 PM Suite:从业务目标到特性列表
基于此思维过程的启发,我们可以分析出 PM Suite 系统应具有
的 Feature,采用“文字描述法”描述如下。
· 功能覆盖4大业务域:单项目管理、项目群管理、项目组合管
理、基础管理。
(说明:显然,此项Feature重复了“需求范围”)
· 单项目管理相关的功能组包括:任务管理、进度管理、范围管
理、……
· 项目群管理相关的功能组包括:项目关联管理、生命周期管
理、……
· 项目组合管理的功能组包括:项目组合分析、项目组合监控、……· “生命周期管理”功能的如下具体特色非常有竞争力:内置
PMBOK、CMMI、GJB 等规范的管理过程模板,通过方便设置即可生效。
· 技术特色:与著名工具的无缝集成。
· 技术特色:二次开发支持。
同样,基于市场宣传的需要,“你”可以将Feature以美化的形式
展示出来,凸显产品特色和卖点。例如图 5-24 和图 5-25,分别来自
北京维普时代和 IBM,用于分别描述这两家公司推出的项目管理产品
的关键Feature。
图5-24 将Feature用于市场材料的例子(图片来源:北京维普时代)图5-25 将Feature用于市场材料的例子(图片来源:lBM)
嗯,的确如此,任凭市场彩页再怎么多“彩”,核心内容必少不
了如下“两高”:
· 一是诸如功能范围、Feature等这些需求分析的“高层成
果”。
· 二是诸如高层架构、技术优势等这些设计的“高层成果”。……如果读者您是开发人员,在看到我们贯穿案例的需求分析环
节和“市场宣传”也能挂起钩来,是否感到吃惊?程序员必须知道,向架构师转型时,必须深刻领会“技术和市场并不是孤立的”。转,既意味着岗位职责的转变,又意味着技术技能的转换,还意味着思维
焦点的转移。
【解惑】
整体来看,Feature(特性)在实践中其实有两种大相径庭的用
法:
· 一种是把 Feature 看做从业务目标向具体需求过渡的手段,它的数量将比具体的用户需求的数量要少一个数量级。这时,Feature
以“高度概括的功能组+少数重要功能项+少数功能实现特色+少数技术
特点”为内容。· 另外一些实践者把特性当做比“功能”更小的需求单位,例如
特性驱动开发(Feature Driven Develo pment,FDD)方法就持这种
观点。实践起来,Feature 的数量将大大多于“功能项”的数量。
本书认为,Feature 的第一种用法对实践非常有帮助。Feature
作为从业务目标向具体需求的过渡手段,启发了未来系统应在大方向
上具有哪些方面的特性(后续可以把每个特性落实到一个或一组功能
中),以一种实实在在的方式加强了需求分析师的系统化思维。
【技能3】高层需求之画上下文图
现在,该画PM Suite的上下文图了。
由于上下文图描述的本系统、相关系统、外部因素、信息流等要
素很大程度上就是在“刻画现实”,因此上下文图是高层需求三剑客
(范围、Feature、上下文图)中“实感性”最高的一个。上下文图画
法,常用的有三种:
· 顶层数据流图。
· 将System处理成黑盒的用例图。
· Powerpoint等绘制的框图。
如图5-26所示,我们采用“顶层数据流图”画法,绘制了PM
Suite的上下文图。
5.5.4 第3步:画用例图
好了,现在我们不仅确定了 PM Suite 的业务目标(4 点目
标),还将目标落实到了“面”状范围(4块内容)、“点”状
Feature(N个特性)、上下文图(系统边界)。
用例建模时,上述成果能起到很大的启发作用:
· 系统外部——用例图的Actor有哪些呢?首先“上下文图”的
外部实体会给你启发。
· 系统内部——用例图的 Use Case 要充分覆盖“范围”的规
定,并体现“Feature”的要求。图5-26 PM Suite:上下文图
例如,根据 PM Suite“组织级项目管理平台”这一定位和需求范
围“基础管理+单项目管理+项目群管理+项目组合管理”这4大业务
域,不难分析出PM Suite的5种用户角色:
· 项目成员。
· 项目经理。
· 部门经理高层。
· 过程经理。
· 系统管理员。
再加上上下文图中明确的和PM Suite 有交互的5个外部系统,用
例图中的10种Actor就确定下来了。如图5-27所示。图5-27 用例图绘制过程:确定System的Actor
再继续,不断明确每个 Actor 相关联的每种用例(具体功能
项),绘制用例图。既然系统较大,就采用多幅用例图的方式:
· 如图5-28所示,该用例图描述了与“系统管理员”和“过程经
理”相关的所有用例。
· 如图5-29所示,“单项目管理”业务域的用例被展现到用例图
中。
·……图5-28 用例图绘制过程:明确部分用例图5-29 用例图绘制过程:明确部分用例
当然,“用例图+用例简述”经常一起出现、配合使用,在此不再
赘述。
5.5.5 第4步:写用例规约
上面,我们梳理了用户需求。所谓用户需求,就是用户希望软件
系统能为他做什么。用例图技术是捕获和记录用户需求的合适技术,1)它清晰地将系统的用户、外部协作系统建模成Actor,2)“以用户
(和外部系统)为中心”梳理系统应当具有的能力,3)将这些能力建
模成用例,为用例命名以最直观地体现用户需求。
接下来,就是写用例规约了。
用例图并不足够。换句话说,需求分析进行到用户需求的层次并
不足够,因为如果不明确定义软件系统的行为需求,我们就不知道要
开发什么。基于用例技术的需求实践中,此时应和用户一起编写用例
规约(对于简单并不易产生歧义的需求可以仅通过“用例简述”说
明)。
仅举一例,如表5-7所示为“添加项目任务”的用例规约。
表5-7 用例:添加项目任务5.5.6 插曲:需求启发与需求验证
在需求分析过程中需要不断地和客户进行交流,这时客户非常希
望能够看到给他带来实际感受的界面草图甚至可执行的系统原型。而
开发方最担心的问题是客户需求的不断变化,所以他们也希望能够尽
早掌握客户的真正需求,并希望需求成果得到客户的确认。为此,我们可以在需求分析期间就开始界面设计(如图 5-30 所
示),并将界面草图等设计成果用于和客户的交流当中,这样可以增
加实感、方便交流,并帮助客户“发现”他真正想要的功能。当然,界面设计的成果一般并不推荐放入《需求文档》,因为它们是设计而
不是需求。
举个例子。在一开始和讨论“添加项目任务”这项需求时,我们
和用户可能都没有意识到两个需求细节:
· 用户希望能为每项任务指定优先级,这样有利于承担多项任务
的项目成员在时间不够时权衡取舍;
· 出于对易用性的极高要求,用户要求确定任务细节的时机必须
非常灵活。
图5-30 界面设计与需求分析
后来,在界面图和可执行原型的帮助下,用户能比较容易地意识
到“令人不满的地方到底在哪儿”,明确提出了上面的“两个需求细
节”,开发方也更新了“添加项目任务”的界面原型。图5-31 展示了
更新后的界面原型:用户既可以只输入任务名称和所属项目就创建任
务,也可以同时指定许多详细信息。图5-31 利用原型启发需求和确认需求
5.5.7 插曲:非功能需求
非功能需求的满足程度对软件项目的成功非常关键,因此需求分
析中必须重视。
一部分非功能需求来自用户。诸如性能、易用性等软件质量属
性,虽然不像功能需求那样直接帮助用户达到特定目标,但并不意味
着软件质量属性不是必需的——恰恰相反,质量属性差的软件系统大
多都不会成功。
还有一部分非功能需求来自开发者和升级维护人员。软件的可扩
展性、可重用性、可移植性、易理解性和易测试性等非功能需求,都
属于“软件开发期质量属性”之列,它们都将影响开发和维护成本。
也有一部分非功能需求来自客户组织。架构师必须充分考虑客户
对上线时间的要求、预算限制,以及集成需要等非功能需求,还要特别关注客户所在领域的业务规则和业务限制。
因此,在实际需求分析工作中,非功能需求的确定很难一蹴而
就,应该时时关心、不断完善。在表5-8中,着重列举了PM Suite的非
功能需求。
表5-8 PM Suite的非功能需求
5.5.8 《需求规格》与基于ADMEMS矩阵的需求评审
后续的需求文档编写和需求评审也很重要,在此不再详述。
《软件需求规格说明书(SRS)》是需求分析工作最重要的成果,本书第 6 章会说明采用用例建模技术时编写《软件需求规格说明书》
的几点注意。
任何一个有经验的设计者都不想“无论 SRS 好坏,唯 SRS 是
瞻”,这就需要需求评审的能力。基于本章讲过的ADMEMS 矩阵(需求
层次—需求方面矩阵)用来检查需求是否全面、是否有遗漏,是一种
务实有效的办法。第6章 用例与需求
需求=功能+质量+约束。用例是功能需求实际上的标准。用例涉
及、但不涵盖非功能需求。
——温昱,《一线架构师实践指南》
仅在需求规格中出现用例图并不意味着应用了用例技术。
——徐锋,《软件需求最佳实践》
几年来,笔者接触了大量开发人员,发现只要是关心设计的开发
人员,都关心用例技术,认为用例技术很流行、很有用,希望更好地
掌握这种技术。
本章立足软件开发人员的视角,抽取一些实际问题,并在最后的
“实际应用”一节解决“用例建模够不够?流程建模要不要?”的常
见困惑,希望对更清晰地运用用例技术有所帮助:
· 用例图、用例规约、用户故事,这些技术有什么关系?
· 如何应用?
· 需求分析的三套实践论中,用例建模和流程建模的关系是什
么?
6.1 用例技术族
用例技术是多种技术组成的“技术族”,不应该一概而论,那种
把所有这些技术一股脑儿称为“用例模型”的做法,不利于学习,也
不利于实践。
本节借助银行的储蓄系统为背景案例,说明这些技术的不同:
· 用例图。
· 用例简述(用户故事)。
· 用例规约。
· 用例实现(鲁棒图)。
6.1.1 用例图用例图描述软件系统为用户或外部系统提供的服务。结合图6-1:
· 用例图最重要的元素是参与者(Actor)和用例(Use Ca
se),以此体现系统能为外部参与者(Actor)提供的功能(Use
Case);
· 参与者是与系统交互的角色或系统,既可以是系统的用户
(User),也可以是和系统有直接交互关系的系统(System);
· 用例的名称应该从参与者的角度进行描述,并以动词开头,这
样一来通过“读图”可以清晰地获得用例图的语义,例如图 6-1 中
“连读”出“柜员开户”、“柜员销户”等语义。
图6-1 储蓄系统用例图的一部分
可见,用例图所做的,一是确定与本系统交互的角色或外部系
统,二是描述系统必须提供的功能。对系统研发而言,用例图以可视
化的方式进一步明确了系统功能范围(Scope)内的所有功能。
6.1.2 用例简述、用户故事
用例图中所含的用例必须被命名,但用例图中所含的用例信息也
仅此而已了。因此,还需要其他的“用例说明技术”对用例进行更进
一步的说明。
用例简述就是“用例说明技术”中最简单、最实用的一种。所谓
用例简述,就是通过简短的文字对用例的功能进行描述;一般而言,用例简述都应包含成功场景的简单描述。如表 6-1 所示,它对储蓄系
统“销户”用例进行了简要描述。
表6-1 储蓄系统“销户”用例简述
很多敏捷方法都通过类似用例简述的技术捕获和交流需求,例如
极限编程(eXtreme Programming,XP)的 ......
您现在查看是摘要介绍页, 详见PDF附件(29145KB,370页)。





