2023年12月9日发(作者:)
-

讲座:从需求分析到系统设计
董祖明, 2005年5月20日
一、八皇后问题
先以八皇后为例,说明从原始需求的描述、到需求的分析、再到系统的设计的逻辑抽象的过程,说明从需求分析的What到系统设计的How。
1、原始需求描述
八皇后问题:把八个皇后放在棋盘上,使任何皇后都不能吃到其他皇后
2、需求分析:
这个需求隐含了国际象棋的规则(业务规则):
国际象棋的棋盘:8行8列的64个方格,棋子放在方格上
皇后的走法:可以走直线、横线、斜线,任意格数
因为皇后可以走任意步数的直线、横线和斜线的米字形棋步,所以八个皇后互相不能吃到其他皇后可以转化表述为同一条直线、横线和斜线上不能有两个或以上的皇后。
由于明显每行只能有一个皇后,可把问题简化为每条横线、上斜线、下斜线上最多只能摆一个皇后。
用数据的方法抽象地表示“同线”的业务逻辑,同一直线上的皇后,横坐标相同;同一横线上的皇后,纵坐标相同;斜线分为上行斜线和下行斜线,下行斜线的横纵坐标之和相等;上行斜线的横纵坐标之差相等。
一共有8条横线、8条直线、15条上斜线、15条下斜线。
3、系统设计:
8x8的棋盘共有8条直线、8条横线、15条上行斜线和15条下行斜线,可以表示如下:
数据结构:
int a[8]; /* 1表示第i行上无皇后 1到8 */ int b[15]; /* 1表示第i条上行斜线上无皇后 2到15 */
int c[15]; /* 1表示第i条下行斜线上无皇后 -7到+7*/
int x[8]; /* 记录第i列上皇后的位置 1到8 */
操作设计:
置放皇后:x[i]=j; a[j]=0; b[i+j]=0; c[i-j+7]=0; /* 0=false */
移去皇后:a[j]=1; b[i+j]=1; c[i-j+7]=1; /* 1=true */
判断安全:a[j] && b[i+j] && c[i-j+7] /* true表示三条线上都无其他皇后 */
这里下标的计算方法决定了数组的边界, 本例是为因为C语言的数组只能从0开始
算法设计:
使用尝试-纠错和回溯方法,递归算法。先找第i行的安全位置放一个皇后,然后尝试在第i+1行的安全位置放下一个皇后,如果第i+1个皇后无处可放,则退回到第i个皇后重新选择另一个安全位置,直到放完8个皇后。
算法概要:
test(i) {
for k=1 to m {
选择第k个候选者
if 可接受 then {
记录它
if i 删除记录 } } } 这是在算法与数据结构的教科书中讲过的一个非常基础的通过试错-回溯来寻找所有解的解题思路。当然也可以转化为等价的8层循环的算法,递归算法表达得更简练。 4、程序设计 #include int a[8]; /* 1表示第i行上无皇后 1到8 */ int b[15]; /* 1表示第i条上行斜线上无皇后 2到15 */ int c[15]; /* 1表示第i条下行斜线上无皇后 -7到+7*/ int x[8]; /* 表示第i列上皇后的位置 1到8 */ /* 打印一个解 */ void print() { int k; for (k=0; k<8; k++) printf("%d ",x[k]); printf("n"); } /* 递归算法 */ void test(int i) { int j; for (j=0; j<8; j++) /* 选择第j个候选者 */ if (a[j] && b[i+j] && c[i-j+7]) { /* 如果可接受 */ x[i]=j; a[j]=0; b[i+j]=0; c[i-j+7]=0; /* 记录它 */ if (i<7) test(i+1) else print(); /* 打印一个解 */ a[j]=1; b[i+j]=1; c[i-j+7]=1; /* 删除记录 */ } } /* 初始化棋盘上无皇后 */ int main(int argc, char* argv[]) { int i; for (i=0; i<8; i++) a[i]=1; for (i=0; i<15; i++) b[i]=1; for (i=0; i<15; i++) c[i]=1; test(0); } 5、结果测试 一共有92个解, 除了对称同构的解,有12个不同的解 0 4 7 5 2 6 1 3 0 5 7 2 6 3 1 4 0 6 3 5 7 1 4 2 0 6 4 7 1 3 5 2 …… 6、案例分析 在获得完整、准确的原始需求描述后,还要发现需求背后潜在的业务规则(建立业务模型),并用通过分析抽象,把问题形式化地表示为简化的方式(建立逻辑模型),再找出解决问题的思路(算法),最后编写程序、测试结果。 Pascal之父Niklaus Wirth, PhD, Berkeley; Prof, ETH Zurich 1984年因开发了EULER、 ALGOL-W、 MODULA和PASCAL一系列崭新的计算语言而获奖。他写过一本非常著名的书: 《算法 + 数据结构 = 程序》 尽管现在在软件开发方法论上有许多新的思想,例如面向对象等等,但本质上仍然符合上述最基本的原理。 二、从需求分析到系统设计的一般方法 1、软件工程 人月神话插图-焦油坑 软件危机 软件开发本质上是从自然语言描述的用户需求到机器语言描述的指令的转换。两者之间距离甚远,要通过需求分析、系统设计、程序设计、系统测试、安装实施等阶梯状的过程来逐步转换。 据统计,世界上的软件开发项目有30%是完全失败的,有50%是在功能欠缺、进度延误、成本超支的,只有20%是成功的。构建软件是复杂度极高的。 《人月神话》提到,开发系统软件产品的难度是普通程序的9倍。 简单来说,一是软件的定义,二是软件的构建。其中软件的定义是最难的,它要跨越很大的鸿沟。 软件开发的本质,在于通过问题分解降低复杂度,从原始需求到最终代码的逐步转换。其难度在于抽象和形式化,在于保持系统设计的概念完整性和一致性。// 自动编程,香肠机 软件开发要以客户为中心,满足客户需求是最重要的。 在现实中,从需求到设计是最容易出现沟通障碍,导致不可逾越的鸿沟,破坏系统的连贯性,从而导致软件开发的失败。错误的需求导致开发的系统非客户所需、并且带来极大的修复代价甚至不可救药,因此错误的需求是最严重的BUG。 所以软件危机更多意义上是软件需求分析的危机。 软件生命周期SLC 瀑布模型 演化模型 螺旋模型 喷泉模型 智能模型 无论哪一种开发模型,关键都有从需求到设计的软件定义的步骤。需求是变化的,开发过程和方法要基于变化的需求来开展,拥抱变化。 // 快速软件开发,敏捷软件过程,CMMi,ISO 9002,RUP 管理信息系统 像酒店管理软件这种管理信息系统,是涉及到硬件、软件、人员、制度、文档等的一个综合性系统。 所有软件系统都可归纳为IPOS:输入、处理、输入、存储 软件工程的目标:多、快、好、省 毛主席教导我们:要多快好省地建设社会主义。// 南京长江大桥 2、需求分析 What 需求分析的任务:需求分析要深入描述软件的功能和性能,确定软件设计的限制和软件同其他系统元素的接口,定义软件的其他有效性需求。 谁做需求分析? 需求的层次: 需求分析的过程: 问题识别:原始需求的收集、整理 分析抽象:分析、抽象、建模 编写文档:编写软件需求说明书SRS 评审验证:用户-SRS-程序员,达成共识 需求变更管理:需求基线和变更控制 需求来源: 书本:系统化的理论和实践 // 知识准备 客户:投资者、使用者(不同层次)// 以客为先,根本之道 历史:软件、文档、同事 // 以史为鉴、可知未来 对手:FIDELIO、HIS、西软 // 他山之石、可以攻玉 技术:需求催生技术,技术引发需求 能力:学习能力、沟通能力、抽象能力、表达能力 需求定义的要求: 准确、完整、一致、简明、无歧义、易读、可实现、划分优先级。 需求调查的一般方法 企业概况:企业目标、业务模式,从总帐入手 组织架构:层次图,矩阵图 岗位职责:部门-岗位-职责 业务流程:部门-岗位-业务-数据,流程图 单证帐表:区分基础数据、导出数据,收集表单样张、计算公式、数据流向 结构化分析方法SA 实体关系图ERD:数据对象、属性、关系、基数+形态 数据流图DFD:数据流、控制流 状态迁移图STD 数据字典DD:数据对象=项目+[选项一|选项二]+{重复项}+(可选项) 设计原则:通过分解和抽象,简化问题、降低复杂度 自顶向下、逐步求精 模块化,模块独立性(高内聚、低耦合) 抽象化:数据、过程、控制 // 抽象数据类型:数据、行为、约束定义 信息隐蔽:Stack示例,可维护、可移植 面向对象的方法:封装、继承、多态 发现类和对象 识别对象内部属性,行为(操作、方法、服务),消息(交互) 识别对象外部关系,归纳、组合、关联 划分类层次、归纳主题 发现活动者、定义用例、建立交互图 编写详细说明 开发原型 统一建模语言UML UML是一种对软件进行可视化、详细描述、迭代构造和文档化的图形化建模语言。 对结构和行为建模。 三种构造:事物、关系、图 四种事物:结构、行为、分组、注释 七种结构:类、接口、协作、用例、主动类、构件、节点 两种行为:交互、状态机 四种关系:依赖、关联、泛化、实现 九种图:类、对象、用例、顺序、协作、状态、活动、构件、实施图 统一软件开发过程 RUP 软件开发生命周期:初始、细化、构造、交付的迭代。 统一过程:用例驱动、以架构为中心、迭代和增量的 3、系统设计 How 系统设计一般包括设计、编程、测试,此处主要指概要设计或逻辑设计。 概要设计、详细设计 数据设计、架构设计、过程设计 数据库设计 分解,一事一地、消除冗余、保持一致 规范化 3NF 索引 模块设计: 分层次的输入-处理-输出 HIPO=Hierarchy Input Process Output 与业务的部门和角色对应 过程设计: PFC=Program Flow Chart 程序流程图 Decision Table / Tree:条件-动作,条件-选择 PDL=Program Design Language 伪语言 界面设计 以后再说 参见:软件工程设计概述.vsd 4、建模工具 一图胜千言:图形化的表达方法 Pencil & Paper Visio PowerDesigner Rational Rose 5、标准文档 可行性分析报告:Scope & Vision 软件需求说明书SRS 系统设计报告 参照国际、书上的模板。 八股文,形式与内容。 三、千里马酒店前台系统 1、需求描述 V7前厅业务描述.doc 袁仲明:前台业务流程图.PDF …… 2、需求分析 数据流图:参见V7 Front Office 实体关系图:参见V7前台系统概要设计.xls 状态迁移图:参见V7前台系统概要设计.xls 数据字典:参见V7前台系统概要设计.xls SRS:参见V7前台系统需求分析报告.doc 3、系统设计 设计原则: 开放性:可扩充、可自定义 一致性:界面风格一致、操作方法一致 面向对象的逻辑三层结构: 数据结构:以客单为核心的客、房、帐结构 业务对象:客房、预订/接待、管家、帐务等 命令解释器:参见V7前台系统业务对象接口.doc 用户界面:动态工作视图、表单 存贮过程:基本过程(过帐、夜核等)、房态预测(团体、散客),统计报表 总结: 从需求分析到系统设计,没有银弹,关键在于沟通、分析抽象、形式化表达的能力。 A、附录:以后的讲座 1、数据库性能优化 讲述从系统配置的硬件、网络、数据库安装和定期维护和优化,到应用程序的查询优化和算法设计,与性能优化的关系和具体方法 2、软件项目管理 讲述项目管理的一般方法,讲述软件项目中人、过程、产品的3P因素。 -