高级软件工程课程总结

来源:互联网 发布:梦龙网络计划99a 编辑:程序博客网 时间:2024/05/23 22:34

1.初识软件工程

1.1软件无处不在

“软件定义世界”成为社会发展的潮流,软件在人类生活中扮演者越来越重要的角色,软件已经成为一个极其重要的产业形态。

软件是软件工程的研究对象,也是软件工程的产品形态与客观存在。

工程是将理论和知识应用于实践的科学,其目的是经济有效地解决实际问题。

1.2软件的本质与特性

软件=程序+数据+文档

软件具有复杂性、一致性、可变性和不可见性等固有的内在特性,这是造成软件开发困难的根本原因。

1.3软件工程的产生与发展

根据美国standish集团的调查报告,软件项目的成功率大概在30%左右。

软件开发面临的挑战:交付的许多功能不是客户需要的,交付的日期没有保障,客户使用时发现许多bug,客户需求变化频繁,无力应对,无法预见软件的交付质量,对流程盲目遵从,忽视客户业务价值,开发团队专注于技术,忽视风险,无能力预测成本,导致预算超支,无法评估开发人员能力及工作进度,困扰于如何提升团队的能力与效率。

发展历史:

(1)史前阶段(1956-1967):软件开发没有方法可循;软件设计是开发人员头脑中的隐藏过程;60世纪中期的软件危机。

(2)   瀑布过程模型(1968-1982):1968年提出“软件工程”结构化开发方法,瀑布式软件生命周期模型成为典型。

(3)质量标准体系(1983-1995):面向对象开发方法,软件过程改进运动,CMM/ISO9000/SPICE等质量标准体系。

(4)20世纪90年代至今:敏捷开发方法流行,更紧密的团队协作,有效应对需求变化,快速交付高质量软件,迭代和增量开发过程。

1.4软件工程的基本概念

软件工程是:(1)将系统性的、规范化的、可定量的方法应用于软件的开发、运行和维护,即工程化应用到软件上;(2)对(1)中所述方法的研究。

软件工程的目标是创造出足够好的软件。

软件工程的基本要素:(1)过程(支持软件开发各个环节的控制和管理);(2)方法(完成软件开发任务的技术手段);(3)工具(为软件开发方法提供自动或半自动的软件支撑环境)。

软件开发活动:问题定义(构想文档,用户故事)》》需求开发(分析模型,软件需求规格说明)》》软件设计(设计模型,软件体系结构文档,软件详细设计文档)》》软件构造(源程序,目标代码,可执行构件)》》软件测试(测试规程,测试用例,测试报告)。

软件工程方法:面向过程(以算法为基本构造单元,强调自顶向下的功能分解,将功能和数据进行一定程度的分离)》》面向对象(以类为基本程序单元,对象是类的实例化,对象之间以消息传递为基本手段)》》面向构件(寻求比类的粒度更大的且易于复用的构件,期望实现软件的再工程)》》面向服务(在应用表现层次上将软件构件话,即应用业务过程由服务组成,而服务由构件组装而成)

软件工程工具:需求开发+软件设计(软件建模工具,数据库设计工具)》》软件构造(程序编辑器、编译器、解释器、调试器、集成开发环境)》》软件测试(单元测试工具,静态分析工具,自动化测试工具,性能测试工具,缺陷跟踪工具)》》软件维护(代码重构工具,逆向工程工具)》》开发管理(需求管理工具,项目管理工具,配置管理工具,测试管理工具)


软件开发的基本策略:软件复用(不仅仅是代码的复用,包括【库函数、类库,模板(文档、网页等),设计模式,组件,框架】),分而治之,逐步演进,优化折中。

例子:使用内存缓冲区方法,读取1468802字节文件时,2048和4096的缓冲大小对性能的提升不大,故选择2048的缓冲大小。

软件过程的Wasserman规范:抽象、软件建模方法、用户界面原型化、软件体系结构、软件过程、软件复用、度量、工具与集成环境。

1.5软件质量实现

软件质量:用户(功能质量)》》开发人员》》(结构质量)》》投资者(过程质量)。

软件过程(过程质量)》》软件产品(内部质量+外部质量)》》产品效用(使用质量)。

好的软件:正确的软件+软件运行正确;

ISO9126质量模型:外部和内部质量(功能性【适合性、准确性、互操作性、安全性】、可靠性【成熟性、容错性、可恢复性】、易用性【易理解性、易学习性、易操作性、吸引性】、效率/性能【时间特性、资源利用】、可维护性【易分析性、易改变性、稳定性、易测试性】、可移植性【适应性、易安装性、共存性、替换性】)

实现软件质量:高质量的设计+规范的编码+有效地测试。


2.编写高质量的软件代码

2.1编程过程与规范

软件编程是一个复杂而迭代的过程,它不仅仅是编写代码,还应该包括代码审查、单元测试、代码优化、集成测试等一系列工作。

软件编程规范是用特定语言相关的描写如何编写代码的规则集合。

Python 的import语句:先import内置模块,再import第三方模块,最后import自己开发项目中的其他模块;这几种模块中用空行分隔开来。

Python的列表推导:

[s['name'] for s in students if s['age']>18]

Python的条件表达式:

return s['name'] if s['age']>18 else s['nickname']

2.2良好的编程实践

模块化程序设计:将一个大的程序按功能分解成一系列小模块。

web应用系统:水平划分(用户管理、权限管理、...、业务功能),垂直划分(应用服务层、业务逻辑层、数据存储层);

基于易变和稳定:认识和识别变与不变的部分,并将之科学地分离开;

基于单一职责:类或者函数应该只做一件事,并且做好这件事;

模块设计》》开发模块之间的接口》》

2.3Python集成开发环境

PyCharm:涉及较多web开发时使用。

2.4代码静态检查




Pykint安装与使用:

pip install -U pylint  #安装最新版的Pylintpylint [options] module_or_package_or_file  #对模块/包/文件运行pykint            --rcfile=<file>  指定检查的配置文件    --ignore=<file>  不进行检查的文件列表            --disable=<msg ids>   关闭某种类型的检查    --f <format> 报告类型,如htmlpylint --help-msg <msg-id>   #查看某种类型问题的帮助pylint --generate-rcfile   #根据当前配置生成配置文件

类型:

C(Convertion,约定)

R(Refactor,重构)

W(Warning,警告)

E(Error,错误)

2.5代码性能分析

优化是对代码等价变换,使得变换后的代码运行结果与变换前的代码运行结果相同,但执行速度加快或存储开销减少。

改进算法,选择合适的数据结构:

良好的算法对性能起到关键作用,因此性能改进的首要点事对算法改进;

算法时间复杂性的排序依次是 O(1)<O(lgn)<O(nlgn)<O(n^2)<O(n^3)<O(n^k)<O(k^n)<O(n!);

对成员的查找访问等操作,字典(dictionary)要比列表(list)要快;

集合(set)的并、交、差的操作比列表(list)的迭代要快;

循环优化的基本原则:尽量减少循环过程中的计算量,在多重循环的时候,尽量将内层的计算提到上一层;

字符串的优化:Python的字符串对象是不可改变的。字符串连接的使用尽量使用join()而不是+。当对字符串可以使用正则表达式或内置函数处理时,选择内置函数;

使用列表解析和生成器表达式:列表解析要比在循环中重新构建一个新的list更为高效,因此可以利用这一特性来提高运行效率。

2.6结对编程实践

结对编程是由两名程序员在同一台电脑上结对编写解决同一问题的代码。


3.单元测试

3.1单元测试概述

单元测试是对软件中的最小可测试单元进行检查和验证。

程序=UT+CODE,测试人员有权利对没有做过UT的代码说No。

单元测试:模块接口(对通过所有被测模块的数据流进行测试),局部数据结构(检查模块中的数据结构是否正确的定义和使用),边界条件(检查数据流或控制流中条件或数据处于边界),独立路径(检查由于计算错误、判定错误、控制流错误导致的程序错误),出错处理(检查可能引发错误处理的路径以及进行错误处理的路径)。

单元测试原则:快速的,独立的,可重复的,自我验证的,及时的。

指标:测试通过率,测试覆盖率。

代码覆盖率:语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖。

单元测试方法:静态测试,动态测试。

Mock测试:在测试过程中对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象(即Mock对象)来创建以便测试的方法。例如,真实对象具有不可确定的行为(产生不可预测的结果),真实对象很难被创建(如具体的web容器),真实对象的某些行为很难触发(如网络错误),真实情况令程序额运行速度缓慢,真实对象有用户界面,测试需要询问真实对象它是如何被调用的,真实对象实际上并不存在。

3.2黑盒测试方法

黑盒测试(black box testing):又称功能测试,它将测试对象看作一个黑盒子,完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。

测试用例(测试集:测试用例值的集合):测试用例值,期望结果,前缀值,后缀值。

测试用例设计:具有代表性和典型性;寻求系统设计和功能设计的弱点;既有正确输入也有错误或异常输入;考虑用户实际的诸多使用场景。

黑盒测试技术:等价类划分,边界值分析,因果图决策表,场景法,组合设计法,状态转换测试。

等价类划分是将输入域划分成尽可能少的若干子域,在划分中要求每个子域两两互不相交,每个子域称为一个等价类。

变量的等价类==》字符串:在规定了输入数据必须遵守的规则情况下,可确定一个有效等价类(符合规则)和若干无效等价类(从不同角度违反规则)。枚举:若规定输入数据是=一组值(假定N个),并且程序要对每一个输入值分别处理,可确定N个有效等价类和一个无效等价类。数组:数组是一组有相同类型的元素的集合,数组长度及其类型都可以作为等价类划分的依据。

测试用例生成:测试对象通常有多个输入参数,如何对这些参数等价类进行组合测试,来保证等价类的覆盖率,是测试用例设计首先需要考虑得问题。

边界值分析:基本思想【故障往往出现在程序输入变量的边界值附近】。

健壮性测试:是作为边界值分析的一个简单的扩充,它除了对变量的5个边界值分析取值外,还要增加一个略大于最大值(max+)以及略小于最小值(min-)的取值,检查超过极限时系统的情况。


3.3白盒测试方法

白盒测试(White Box Testing):又称结构测试,它把测试对象看做一个透明的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有的逻辑路径进行测试。

测试覆盖标准:测试需求,覆盖标准,测试覆盖,覆盖程度。

控制流图(CFG,Control Flow Graph)是一个过程或程序的抽象表示。控制流图的基本符号:矩形代表了连续的顺序计算,也称基本块;节点是语句或语句的一部分,边表示语句的控制流。

基于控制流的测试:


代码覆盖率标准:代码覆盖率描述的是代码被测试的比例和程度,通过代码覆盖率可以得知哪些代码没有被覆盖,从而进一步补足测试用例。

判定覆盖(分支覆盖):程序中每个判断的取真和取假分支至少经历一次,即判断真假值均被满足。

条件覆盖:每个判断中每个条件的可能取值至少满足一次。

判定条件覆盖:判断中所有条件的可能取值至少执行一次,且所有判断的本身的结果也至少执行一次。

条件组合覆盖:判断中每个条件的所有可能取值组合至少执行一次,并且每个判断本身的结果也至少执行一次。

路径覆盖:前面的测试用例完全覆盖所有路径,但没有覆盖所有条件组合。

基本路径测试:是在程序控制流图基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法。

循环测试:目的是检查循环结构的有效性;类型是简单循环、嵌套循环、串接循环和非结构循环。

3.4单元测试工具

Python单元测试工具之unittest。


4.软件开发过程

4.1软件过程

过程:程序(规定过程实现的方法途径和步骤);监视测量(过程前、中、后);

软件开发管理与支持活动:软件项目管理计划、软件配置管理计划、软件质量保证计划、评审记录......

需求开发:在可行性研究之后,分析、整理合提炼所收集到的用户需求,建立完整的需求分析模型,编写软件需求规格说明。

软件设计:根据需求规格说明,确定软件体系结构,进一步设计每个系统部件的实现算法、数据结构及其接口等。

软件构造:概括地说是将软件设计转换成程序代码,这是一个复杂而迭代的过程,要求根据设计模型进行程序设计以及正确而高效地编写和测试代码。

软件测试:检查和验证所开发系统是否符合客户期望,主要包括单元测试、子系统测试、集成测试和验收测试等活动。

软件维护:系统投入使用后对其进行改进,以适应不断变化的需求。完全从头开发的系统很少,将软件系统的开发和维护看成是一个连续过程更有意义。

软件项目管理:是为了使软件项目能够按照预定的成本、进度、质量顺利完成,而对成本、人员、进度、质量和风险进行控制和管理的活动。

软件配置管理:是通过执行版本控制、变更控制的规程,并且使用合适的配置管理软件,来保证所有产品配置项的完整性和可跟踪性。

4.2软件过程模型

瀑布模型:将基本的开发活动看成是一系列界限分明的独立阶段,这是一种计划驱动的软件过程,有利于规范软件开发活动。

原型化模型:原型是一个部分开发的产品,用于加强对系统的理解,有助于明确需求和选择可行的设计策略。

迭代式开发:将描述、开发和验证等不同活动交织在一起,在开发过程中建立一系列版本,将系统一部分一部分地逐步交付。

可转换模型:利用自动化的手段,通过一系列转换将需求规格说明转化为一个可交付使用的系统。


业界已经很少使用瀑布模型。

软件开发具有迭代性。



增量模型:在每一个新的发布中逐步增加功能直到构造全部功能。

迭代模型:一开始提交一个完整系统,在后续发布中补充完善各子系统功能。


4.3敏捷开发过程

敏捷开发是一种基于更紧密的团队协作、能够有效应对快速变化需求、快速交付高质量软件的迭代和增量的新型软件开发方法。

内容:个体和交互胜过过程和工具;可以工作的软件胜过面面俱到的文档;客户合作胜过合同谈判;响应变化胜过遵循计划。

敏捷开发方法是一组轻量级开发方法的总称,包含很多具体的开发过程和方法,最具有影响的两个方法是极限编程(XP)和Scrum开发方法。


Scrum迭代开发:将整个软件生命周期分成多个小的迭代(一般2~4周),每一次迭代就是一个小的瀑布模型,包括需求分析、设计、实现和测试等活动,结束时都要生成一个稳定和被验证过得软件版本。

4.4微软公司开发过程


5.团队开发管理

5.1团队组织与管理

人力资源规划》项目团队组建》项目团队建设》项目团队管理。

系统分析员(需求分析和定义、系统设计),系统架构师(系统设计、程序设计),程序员(程序设计、程序实现),测试人员(单元测试、集成测试、系统测试),培训人员(系统交付、维护)。

开发团队组织模式:民主式结构(团队成员完全平等,享有充分民主,成员之间通过协商做出决策);主程序员式结构:以主程序员为核心,主程序员既是项目管理者也是技术负责人,团队其他人员的职能进行专业化分工。

矩阵式结构:将技术与管理工作进行分离,技术负责人负责技术上的决策,管理负责人负责非技术性事务的管理决策和绩效评价。

5.2项目沟通管理

关键:交流,交流,再交流

5.3软件项目计划

软件项目计划是对软件项目实施所涉及的活动、资源、任务、进度等进行规划。按时交付时软件项目的最大挑战,合理地安排进度是软件项目计划的关键内容。

开发问题描述》定义顶层设计(描述了最初从系统到子系统的分解,它描述了系统的软件体系结构)》定义工作分解结构》建立初始时间表

5.4软件项目估算

项目估算是对完成项目交付物的时间和成本进行预算和估计的过程。

参数估算:通过对大量的项目历史数据进行统计分析,使用项目特性参数建立经验估算模型,估算诸如成本、预算和持续时间等活动参数。

(1)功能点方法:是依据软件信息域的基本特征和对软件复杂性的估计,估算出软件规模。这种方法适合于在开发初期进行估算,并以功能点为单位度量软件规模。

软件信息域:外部输入、外部输出、外部查询、内部逻辑文件、外部接口文件。

(2)结构成本模型COCOMO(COnstructive COst MOdel):是一种利用经验模型进行工作量和成本估算的方法。


(3)用例点估算:是在帮面向对象软件开发项目中用于估计规模和工作量的方法,它比功能点方法要简单一些。

计算角色复杂度(简单:通过API或接口与系统进行交互);一般:通过TCP/IP协议与系统进行交互;复杂:通过GUI或web界面进行交互)》》计算用例复杂度(简单:1个数据库,3步操作,5个类;一般:2个数据库,4-7步操作,5-10个类;复杂:3个数据库,7步操作,10个类)》》计算未平衡用例点》》用技术复杂度因子TCF和环境复杂度因子CEF进行调整,得到用例点》》估算项目开发工作量,主要给出基于每个UCP完成的时间,就可以计算出项目开发工作量。

(4)机器学习方法:

神经网络是采用一种学习方法导出一种预测模型,这种方法使用历史项目数据训练网络,通过不断学习找出数据中的规律,再用其估算新项目的工作量。


基于案例的推理方法可以用于基于类推的估算,即识别出与新项目类似的案例,再调整这些案例,使其适合新项目的参数。


6.敏捷开发与配置管理

6.1敏捷开发之Scrum

Scrum框架:一个Sprint是一个1-4周的迭代,它是一个时间盒;Sprint的长度一旦确定,将保持不变;Sprint的产出是“完成”的,可用的,潜在可发布的产品增量。

Scrum制品:产品订单+迭代订单+可工作软件。

可视化管理:任务白板,燃尽图。

Scrum规划:发布规划;迭代规划。

迭代计划会议在,每次迭代(或冲刺)开始时召开,一般是2~4小时,目的是选择和估算本次迭代的工作项。

6.2用户故事与估算

用户故事(User吧 Story)是从用户角度对功能的简要描述。

格式:作为一个<角色>,可以<活动>,以便于<价值>。

特点:独立性、可协商、有价值、可估算、短小的、可测试。

敏捷估算:故事点(相对度量单位),理想时间(绝对单位)。

理想时间的估算方法:团队查看每个用户故事,针对前面介绍的复杂性要素讨论故事,然后估计要用多少理想时间可以完成该故事。

敏捷估算原则:开发团队一起估算,产品负责人和Scrum主管不参与实际估算。

6.3团队协作工具Tower

https://tower.im/

6.4配置管理

软件配置管理是一种标识、组织和控制修改的技术,它作用于整个软件生命周期,其目的是使错误达到最小并最有效地提高生产率。

软件配置项(Software Configuration Item,简称SCI)是为了配置管理而作为单独实体处理的一个工作产品或软件。

版本是在明确定义的时间点上某个配置项的状态;版本管理是对系统不同版本进行标识和跟踪的过程,从而保证软件技术状态的一致性。

基线(Baseine)是软件配置项的一个稳定版本,它是进一步开发的基础,只有通过正式的变更过程才能改变。

版本控制:独占工作模式;并行工作模式。

分支管理:分支包含了一个项目的文件及其发展的历史,记录了一个配置项的发展过程。一个配置项可能选择多个分支,归并是将对分支的修改合并到另一个分支。

6.5配置管理工具Git

版本控制对于大中型软件系统的开发非常重要。

最早为Linux内核项目管理而开发的git工具受到大量其他项目的欢迎。

git是分布式的“饭桶”。

git的基本概念---版本库:远端版本库,本地版本库。

git版本库的操作部---创建于提交:git init  >>  git status  >> git add file.txt  >> git commit -m "msg"  >>  git status  >>  git add *.txt

>>  git commit -m "msg2"

git版本库的操作---克隆到本地:git clone username@domain:path

比如GitHub版本库一般是git@github.com:用户名/版本库名

其实这是SSH格式的url,也可以用其他的格式,比如GitHub也提供了HTTPS

git版本库的操作---从远端拉取:git pull  >>  git add file4.txt  >>  git commit -m "msg3"  >>  git push

git版本库的操作---撤销变动:git add file4.txt  >>  git reset HEAD file4.txt  >>  git checkout -- file4.txt

git版本库的操作--修改提交:git commit -a -m "msg4"  >>  git add file4.txt  >> gti commit --amend

git的基本概念---分支:git checkout -b week1 >> git commit -a-m "msg5" >> git push -u origin week1

gti分支的操作---合并:git checkout week1 >> git commit -a-m "msg6" >> git checkout master >> git merge week1

gti分支的操作---删除:git checkout master >> git branch -d week1 >> git push origin --delete week1

图形管理软件:https://www.sourcetreeapp.com/


7.需求分析

7.1需求工程师

7.2需求定义

“需求”是对外可见的系统特征。

“需求管理”有三项任务:学习——需求获取;剪枝——需求优选;文档化——撰写需求规格说明书。

每一个“人造物”都是一个内部环境与外部环境的“接口”。对这个接口的描述就是需求。

7.3需求的类型

需求分类:(1)产品/过程:产品需求吗,过程需求;(2)产品需求:功能性需求,非功能性需求;(3)抽象层次详细程度:业务需求,用户需求,系统需求,软件设计规约。

业务需求:业务目标,指可以帮助企业达成组织目标的需求项。

系统需求:使得系统实现预期的功能,它从用户的角度描述系统在做什么,与系统是由什么硬件和软件实现无关。

软件需求:是指关于系统中软件部分的需求,它的满足帮助实现系统需求。

用户需求:是指其满足会影响系统的用户接受程度的需求,有时候,被称为“用户接口需求”。

功能性需求:是指满足系统需求需要提供的功能,有时候,也被称为“行为需求”。

非功能性需求:定义软件系统以及软件开发过程为满足系统功能需求要满足的其他约束条件。

质量需求:描述软件系统正常工作时需要满足的额外的、与质量相关的要求,也称之为“质量属性”。

依从性需求:着重描述软件对国家法律、国际公约、社交法则、文化与政治习惯、标准等环境约束的满足要求。

体系结构设计需求:系统环境对待设计系统在结构上的约束。分布式约束:要求软件系统组件满足目标组织由于地理自然分布导致的对系统设备各节点的分布要求,以及数据的分布式存储于处理要求。安装约束:要求软件系统能够在目标实现环境下正常运行。

设计开发约束:是对软件系统设计过程的约束。包括:开发成本、开发周期、产品特征的变化性、可维护性、可重用性、可移植性等。

7.4需求的主要来源

需求过程活动:需求抽取(Elicitatiobn),需求分析(Analysis),需求规约(Specification),需求管理(Management),需求验证(Validation)。

需求抽取技术:协同工作,面谈,问卷调查,观察法,原型法,文档分析,建模,角色扮演,非功能性需求列表。冲突识别与磋商。

需求分析:对产品及其与环境的交互进行更深入的了解,识别系统需求,设计软件体系结构,建立需求与体系结构组件间的关系,在体系结构设计实现过程中进一步识别矛盾冲突,并通过干系人之间的协调磋商解决问题。

需求验证:对其他需求工程活动的质量的保证。通过数学的形式化工具或工程化的测试过程来确保系统满足干系人的要求。验证方法:评审、原型化、模型验证、确认测试。

需求管理:涉及软件配置管理、需求跟踪、影响分析和版本控制。需求跟踪、变更请求管理、需求属性管理。

7.5需求工程过程

四世界模型:主题世界+系统世界+开发世界+应用世界。

出发点:确定干系人》定义边界》定义目标与情景实例》分析可行性》分析风险。

干系人的参与至关重要。

分析现有系统有助于了解未来系统的工作数据。

7.6需求获取技术

包括:面谈、问卷调查、群体诱导技术、参与调查法、文档分析、头脑风暴、情景分析、原型化方法、建模方法、需求讨论会。

竞争性需求分析:需求、方法、收益、竞争、推广。

A/B测试:确定待试验的两种UI,确定衡量标准,确定数据搜集流程,确定试验运行时间,确定人数,A/B测试的技术实现,搜集数据,分析数据,做出结论。

用户行为数据在线采集:用户操作数据采集(交互过程数据、眼动数据、页面访问时间、访问内容数据、用户偏好数据等),操作数据统计(产商、版本、IP地址、日访问量、地域信息、访问频次、用户身份、访问时长、打分等)。

获取技术选择:界面(原型、情景与建模),业务逻辑(参与观察、亲身实践、面谈和情景),信息(面谈,现有系统分析)。

7.7撰写需求文档

组织形式:

(1)文档需要有逻辑组织结构:参照IEEE的模板

(2)典型的组织形式包括:按系统能够响应的各种外部环境情况来组织;按系统特征来组织;按系统的响应方式来组织;按所管理的外部数据对象来组织;按用户类型来组织;按软件的工作模式来组织;按子系统的划分来组织。

软件需求规格说明SRS的风格:描述性的自然语言文本(用户故事);从用例模型产生(用例模型与需求转化可看成可逆的过程;如果需求模型以用例的形式表示,我们可以逆向生成需求的完整集合);从需求数据库中生成(商业需求数据库有内置的功能来生成经过筛选的需求规格说明;从产品线需求规格数据库中生成特定产品的需求规格说明);从混合模型中生成(特征模型和用例模型)。

用户手册大纲:介绍(产品总览及基本原理;术语和基本特征;展示格式与报表格式的总结;手册的大纲);开始(开始指令;帮助模式;样例运行);操作模式(命令行/对话框/报告);高级特性;命令语法和系统选项。

IEEE-830 SRS模板大纲(介绍,术语表,用户需求规格说明,系统结构,系统需求规格说明,系统模型,系统的演化,附录,索引)。

IEEE-830 SRS模板第三部分:



8用例建模

8.1用例建模概念

为什么需要用例建模---描述系统的功能性需求:

关联干系人需要以及软件需求;确认与系统交互的人或对象(参与者);定义系统的边界;捕捉和传达系统的理想行为(用例);验证或确认需求;规划工具。

用例模型的表示---文本描述。

用例图的主要元素:参与者(与系统交互的人或外部系统);用例(系统为参与者提供的有价值的服务功能);关联(用例图中用例与参与者之间的交互关系)。

什么是用例?定义系统的一系列行为,通过此可以为参与者提供有价值且可观测的结果。

用例包含软件系统需求:用例【定义一个参与者要用到的系统功能;描述系统为实现参与者价值所开展的行为序列;对参与者与系统之间的交互活动进行建模;从特定的用户角度出发,是完整的,实现特定用户价值的事件流】

8.2用例建模过程

用例图》》用例提纲》》用例详细规约。

第一步:找到所有的参与者和用例(识别出参与者并做简单的描述,识别出用例并做简单的介绍)》第二步:编写用例(给用例事件流程划分重要等级,按照重要程度排序详细描述事件流程)。

用例的命名:表明参与者的目标或者作用;使用主动语态;设计一些列操作流程(to-do-list)。

去掉所有的CRUD类的用例:创建(create),查找(retrieve),更新(updata),删除(delete)。

用例的生命周期:用例识别》用例简述》用例提纲》用例详细规约。

Use Case模型的建立步骤:

(1)找出系统外部的参与者和外部系统,确定系统的边界范围;

(2)确定每一个参与者所期望的系统行为;

(3)吧这些系统行为命名为Use Case;

(4)使用泛化、包含、扩展等关系处理系统行为的公共或变更部分;

(5)编制每一个Use Case的脚本;

(6)绘制Use Case图;

(7)区分主事件流和异常情况的事件流,可以把表示异常情况的事件流作为单独的Use Case处理;

(8)细化Use Case 图,解决Use Case 间的重复与冲突问题。

8.3用例建模精讲

(1)设定系统边界

系统边界:一个系统所包含的所有系统成分与系统以外各种事物的分界线;系统边界会对用例以及参与者的定义有所影响。

(2)功能分解

将问题分解为粒度小,独立的部分。

不同的模块协同工作,体现系统的功能。

通常,一些功能分解并没有实际的意义。

(3)何时使用包含关系:

当多个用例有共享行为时,使用包含关系。

为共享行为单独创建用例,被相关用例“包含”。

(4)何时使用扩展关系:

一个用例与另外一个用例近似,只有少许额外的活动。

将代表普遍或基本行为的情况定义为一个用例。

将特殊的、例外的部分定义为扩展用例。

(5)用例图中的主要图标


8.4建模工具介绍

系统建模工具的主要功能:

可视化表达:UML模型;Web模型,例如Azure;数据库模型,例如Power Designer;用户自定义模型,例如Visio。

画图工具:StarUML,Visio

常用系统建模工具(UML2.0):IBM Rational Rose ;JUDE;Enterprise Architect(EA)。

8.5微信抢票应用案例

(1)参与者列表:活动参与者,活动组织者,后台管理员,微信平台,系统时针。

(2)用例列表:发布活动,管理活动,绑定用户,退票,抢票,选择座位,浏览活动信息,推送活动。


9.面向对象分析与设计

9.1面向对象分析

面向对象分析(Object-Oriented Analysis,OOA):

面向对象分析技术关注应用领域中的实体,并将其建模为对象;

面向对象分析技术主要基于分裂、泛化、聚合关系在对象集合之间建立结构;

对象的行为时执行预定的动作(服务/活动);

对象通过执行动作来完成状态变迁。

面向对象分析的起源:

面向对象程序设计(OOP):将OOP中的概念上推到分析和设计阶段;

数据库设计:将数据语义建模概念,如实体-关系、泛化、聚合和分类用于系统分析和设计;

结构化设计:将结构化分析方法与技术,如SADT方法等用于系统分析与建模;

知识表示:采用基于问题框架和语义网络的知识表示方法。

举例:

Peter coad的面向对象方法【coad91】

“对象”是问题领域中真实存在的实体,有“定义清晰的边界”;对象中封装有属性和行为;面向对象分析的五个核心概念:对象、属性、结构、服务和主题。

继承/一般-特殊结构(Gen-Spec Structures)

一般-特殊结构将类组织成基于继承关系的分类层次结构;自底向上是从特殊到一般的类(generalization);自顶向下是从一般到特殊的类(specialization)。

整体-部分结构(Whole-Part Structures)

整体-部分结构描述对象间的组合关系。例如,一个交通灯对象由0-3个灯组,支撑杆和位置对象组合而成。

服务建模(Services)

对象为其周遭的其他对象提供服务,例如,医生对象对外提供的服务包括:体检、出体检报告。

三种服务的类型:瞬时服务Occurrence services(对象的创建、结束、修改等);计算服务Calculate services(对象为其他对象完成计算任务等);监控服务Monitor services(对象持续监控流程,检查预设条件是否满足)。

用带箭头的虚线来表示一个对象引用另一个对象的服务。==服务关系(services relationships)

面向对象的分析方法学

识别对象和类(类是对象的抽象定义);

识别类之间的关系,建立由继承和组合关系组成的类层次结构;

定义主题,通过主题将对象模型组织成多个抽象层次或视角,一般说来通过继承关系或整体部分关系联系起来的类同属于一个主题;

识别各个对象内部的属性信息,并将其赋予相应抽象层次的类;

为每个类定义服务。

9.2CRC卡片分拣法

识别类的方法

根据用例描述中的名词确定类的候选者;

使用CRC分析法寻找类:CRC是类(class)、责任(responsibility)和协作(collaboration)的简称,CRC分析法根据类所要扮演的职责来确定类;

根据边界类、控制类和实体类的划分来帮助发现系统中的类;

参考分析、设计模式来确定类。

对象几乎无处不在

外部实体(与建模中系统存在交互);事物(建模的应用领域中存在的事物);事件(系统上下文中发生);角色(由与系统交互的人扮演的角色);组织单元(与应用领域相关的部分);位置、地点(建模中的问题的物理上下文);结构体(定义类或者对象组合)。

不能定义为类的事物:过程(打印、转换);属性(兰颜色,50Mb)。

类筛选

排除以下的类:超出问题关注范围的类;指代整个系统的类;功能重复的类;过于含糊或过于具体的类;可观察到的现象是,实例对象过多过少。

筛选原则:保存对象信息;提供所需服务;具有多个属性;具有公共属性;具有公共操作;外部实体。

类识别

从原始资料中识别类:找出干系人提交的问题描述中名词即短语;如果他描述应用领域中的信息结构或本质,则加入模型。

从其他来源识别类:背景信息调查,用户及干系人提供,分析模式;

最好识别出尽可能多的候选类:之后逐步按照其价值功用进行选择;明确判断后排除一个类要比压根不考虑来的合理。

识别职责类的功能职责

功能职责关乎行为动作,因此是问题描述中的动词...

识别类交互协作关系:用UML用例图

识别对象及其消息交互

注意:目的并非写出所有场景,而是对类和职责定义进行精化...

9.3面向对象设计

面向对象设计过程

进行适当的领域分析;

撰写问题描述,确定系统的开发任务;

基于问题描述抽取需求;

开发用户界面原型;

识别对象类;

定义每个类的职责;

确定类之间的交互关系;

建立系统的设计模型。

面向对象思维方式的核心理念

区分接口与实现【接口的标准化vs实现的演化】;

用户代码==》接口==》oracle、db2、SQLany

从具体到抽象;

抽象的接口:向用户暴露尽可能少的实现细节;

让用户知道的过于类的内部实现细节越少越好;

最小用户负担原则;

确定用户:面向服务的原则(services principle)

确定对象行为:用例!!以往的设计决策在我们定义抽象接口时候会发生变化;

识别环境约束:环境对对象的行为施加约束限制条件:前置条件/后置条件/例外条件...
确定实现细节:公共接口以外的内容都可以看做是实现相关的。

最小接口原则

开闭原则(Open/Closed Principle,OCP):

最初由Bertrand Meyer提出;

软件实体在扩展性方面应该是开放的,而在更改性方面应该是封闭的。

依赖倒置原则(Dependency Inversion Principle,DIP):

依赖倒置原则指的是依赖关系应该是尽量依赖接口(或抽象类),而不是依赖于具体类。

接口分离原则(Interface Segregation Principle,ISP):

在设计时采用多个和特定客户类(client)有关的接口要比采用一个通用的接口要好。分为:使用通用接口设计和使用分离接口设计。

系统设计的特征

用户友好,易理解, 可靠,可扩展,可移植,可伸缩,可重用,...,简单性:实现简单,使用简单,理解简单,维护简单;

9.4类图建模 

什么是类?

类是具有以下特征的对象集合:相同性质(attributes),相同行为(operations),相同的对象关系,相同的语义(“semantics”)。

对象

对象是类的实例,表示为:两个不同的对象可以有相同的属性取值(正如两个同名的人,或者住在同一栋楼的人);

对象与其他对象之间发生关联关系;

注意将属性划归正确的类。

类属性定义

属性在类图标的属性分隔框中用文字串说明,UML规定属性的语法为:【可见性】属性名【:类型】【【多样性【次序】】】【=初始值】【{约束}】

类关系

对象并非遗世独立,对象间存在千丝万缕的联系

UML中,关注以下几种类型的关系:

关联关系(association)

聚合与组合关系(aggregation and composition)

泛化关系(generalization)

依赖关系(dependency)

实现关系(realization)

类图描述类和他们之间的关系

关联关系的“多样性/维度”(multiplicity)

关联类

有时要为关联相关信息的存储定义一个专门的类,称为“关联类”

保存于关联关系本身相关的信息;

这些信息不属于关联所连接的两端的类。

限定关联(Qualifier)

在关联端紧靠源类图标处可以有限定符(Qualifier)。带有限定符的关联称为限定关联(qualified association)。

说明:

1.限定符是关联的属性。

2.限定符的作用是,给定关联一端的一个对象和限定值,可确定另一端的一个对象或对象集。

聚合(aggregation)与组合(composition)关系

聚合(aggregation)用于表达一个整体对象与其他成员对象之间的关系

“Has- a” 或是“Whole/part”

组合(Composition)用于表达一个整体对象与其组成部分之间的关系

组合关系的对象不存在是,部分类的对象也不存在

整体类对象撤销之前要负责将部分类对象撤销

继承/泛化(inheritance/generalization)

子类继承父类的属性、关联和操作;

子类可以覆盖继承来的内容;

父类可以声明为抽象类(abstract),则将不会为它直接创建实例对象。

继承/泛化(inheritance/generalization)关系的定义

继承/泛化关系建模的意义在于系统环境发生变化时便于添加新的子类;

继承/泛化关系建模的过程:

自顶向下:将某个类分割为属性和操作不同的子类,或者发现关联关系定义的是分类关系“kind of”;

自底向上:为现有的多个具有公共属性及方法的类,定义一个父类;

总结建立类图的步骤:

1.研究分析问题领域,确定系统的需求。

2.发现对象与类,明确它们的含义和责任,确定属性和操作。

3.发现类之间的关系。把类之间的关系用关联、泛化、聚合、组合、依赖等关系表达出来。

4.设计类与关系。调整和细化已得到的类和类之间的关系,解决诸如命名冲突、功能重复等问题。

5.绘制类图并编制相应的说明。

类图建模风格

1.属性名和类型应该一致;

2.不要对有关联类的关联命名。

3.静态操作/属性要在实例操作/属性之前列出。

4.以可见性降低的次序列出操作/属性

5.避免已被语言的命名规范所隐含的版型

6.总是指明多样性

7.不要对每个依赖关系都建模

8.将子类放在超类的下方

9.小心基于数据的继承

10.按惯例是把整体画在部分的左边


10.行为建模

10.1顺序图概念

交互行为建模——顺序图

顺序图用来刻画系统实现某个功能的必要步骤。

顺序图建模元素——对象(Object)及其生命线(Lifeline)

对象以某种角色参与交互

可以是人、物,其他系统或者子系统

生命线:表示对象存在的时间

控制焦点/激活期(Focus of Control/'Activation),表示对象进行操作的时间片段

顺序图建模元素——消息(Message)

消息(Message)用于描述对象间的交互操作和值传递过程

消息类型:

Synchronous同步消息(调用消息)

Asynchronous异步消息

Return 返回消息

Self-message自关联消息

Time-out 超时等待

Uncommitted/Balking阻塞

消息的表示形式

例子:

2:display(x,y) 简单消息

1.3.1:p:=find(specs) 嵌套消息,消息带返回值

4[x<0]:invert(x,color) 条件消息

3.1**:updata() 循环消息

A3,B4/C2:copy(a,b) 线程间同步

10.2顺序图建模

绘制顺序图

1.在顺序图顶端绘制矩形框,定义参与交互的类实例(对象)名;

2.在每个对象下面绘制竖直虚线,表示该对象的生命线;

3.在对象间添加箭头表示各种类型的消息,跟踪对象间的控制流;

4.生命线加竖直矩形定义对象激活器,表明对象正在执行得控制流;

5.根据需要添加框的组合与关联,表示复杂的控制结构。

顺序图建模过程:

参与者:顺序图中有关的对象或者实体

消息:参与对象之间的通信,通过箭头表示

顺序图的起始是一个没有发起对象的消息

每个消息代表的操作属于消息接受方

轴:

横轴:表明正在进行操作的对象/参与者

纵轴:时间(向下表明时间的顺延)

组合框:复杂控制结构表示

框(Frame):框中包含顺序图的部分结构,表示选择(selection)或者循环(loop)结构,左上角注明结构类型,[]中注明条件。

 顺序图间的关联

当一个顺序图过大

需要引用其他图表时,选择下述表示:

不完整的箭头和注释

通过名为“ref”的框图引用相关图表

对象的创建于撤销

创建(creation):“new”标明的箭头

用例场景中新建的对象在图中的位置较低

撤销(deletion,destroy):生命线底部的“X”

注:在Java没有明确的销毁对象的操作,通过垃圾回收机制处理

10.3顺序图风格

顺序图与用例的关系1

顺序图表达单个情景实例的行为;

每个用例对应一个顺序图;

顺序图表达对象间如何协作完成用例所描述的功能;

顺序图用于表示为完成用例而在系统边界输入输出的数据以及消息;

顺序图也用于表示系统内部对象间的消息传递。

顺序图与用例的关系2

顺序图可帮助分析人员对用例图进行扩展、细化和补遗;

顺序图可用于开发周期的不同阶段,服务于不同目的,描述不同粒度的行为;

分析阶段的顺序图不要:

包含设计对象;

关注消息参数。

顺序图建模风格

建模风格1:把注意力集中于关键的交互。

创建模型时要把注意力集中于系统的关键方面,而不要包括无关的细节。

建模风格2:对于参数,优先考虑使用参数名而不是参数类型。

建模风格3:不要对明显的返回值建模。

建模风格4:可以把返回值建模为方法调用的一部分。

顺序图常见问题分析

顺序图中时间约束的表示:用约束(constraint)来表示。

激活期(activation):表示对象执行一个动作的期间(直接操作或者通过下级操作),也即对象激活的时间段。

控制焦点和激活期是同一个概念。

顺序图中递归的表示:利用嵌套的FOC表示。

10.4状态建模

“开关”==有限状态机的建模。

什么是状态?一个对象的状态空间;具体状态与抽象状态。

有限状态机的主要元素:状态和转移

    事件和行为

对象及其状态

所有的对象都有“状态”

对象存在或者不存在

对象不存在也是一种状态

如果对象存在,则具有相应表示其属性的值

每一种状态表示一种可能的状态赋值

有限状态机

有限数量的状态(所有的属性取值为有限的范围)

模型可以表示动作序列(状态变化)

状态空间

对于大部分对象而言,状态空间是非常庞大的

状态空间的大小是对象每个属性取值空间的乘积加1

如果忽略计算机表示的局限性,状态空间是无限的

状态的抽象表示

但往往状态空间中的局部更有探究的价值

有一些状态是不可能出现的状态

整数或实数值属性往往只在一定范围内取值

通常,我们只关注特定约束下的对象及其行为

模型建立的过程——状态空间的分解

抽象之后的模型可以表达更多的状态序列

对什么建模?

领域特征(domain properties):应用领域实体的可观测状态

模型表达了实体可能处于的状态,以及什么操作会造成状态的变化;

是一种描述(indicative)模型:描述实体当前的状态

需求(requirements):应用领域实体所需要的行为

模型可以区分一系列状态序列或操作路径是否能达到预期的结果

是一种愿望(Optative)模型:描述动作及其预期结果

计算机、程序:机器领域实体的具体行为

模型表达了机器该如何响应输入的事件

这是一个愿望(Optative)模型,所有的事件是共有的

10.5状态图

状态图(State Chart/State Machine Diagram)

状态图用来表示一个类的全生命周期过程

状态图建模

建模元素

状态

事件

状态转移

特殊的状态

初始状态、结束状态

组合状态、嵌套状态

历史状态

状态图的绘制

状态

定义:一个对象生命周期的一个阶段,该阶段中对象要满足一些特定的条件、执行特定的活动或等待某个(些)事件的发生。

体现为对象属性的取值;

包含状态入口或出口行为描述;

从不同的抽象层次分析对象,因此其状态是可嵌套(组合)的

在给定的场景下,对象状态是确定的,可满足或不满足某个状态

事件

定义:可以触发对象状态改变的外部刺激,也就是消息的发出与接收

决定状态迁移何时发生

状态迁移

定义:是状态之间的关系,当发生一个事件,条件满足时就会发生从源状态(Source State)到目标状态的转变(Object State)

当且仅当迁移条件满足时才能触发“事件”;

每个状态迁移都对应一个触发“事件”

同时还需要满足一定的“警戒条件(Guard Condition)”

当触发事件发生,或相关警戒条件满足时,进行相应的状态迁移

状态迁移的过程会伴随相关的对象操作

UML状态图中的状态(State)

一个状态表示在某个时间段内

某个陈述是正确的

某个动作正在执行或者在某个时间等待触发

状态相关的活动模型

do/activity

只要处于这个状态,某个活动就会一直执行,直到离开这个状态

entry/action  and  exit/action

当进入(/离开)某个状态时执行的动作

include/stateDiagramName

调用另一个状态图,形成嵌套的状态图

UML状态图中的迁移(Transitions)

迁移包括五部分:源状态(source state)、触发事件(event trigger)、警戒条件(guard condition)、动作(action)、目标状态(target state);

对于给定的状态,最终只能产生一个迁移,因此从相同的状态出来的、事件相同的几个迁移之间的条件应该是互斥的。

UML状态图中的事件(Event)

事件(Events)的意义在于系统需要了解正在发生什么

状态图中,事件仅需和系统或当前建模的对象相关

从系统角度出发,事件必须建模成一个瞬可完成的动作

在UML中,有四种类型的事件

变更事件(change events),当给定条件成立时就会发生变更事件

通过布尔表达式中变量的改变,使得表示式成立的事件,通过“when”关键字进行提示

调用事件(call events),当给定对象的操作被调用执行时会发生调用事件

在这一类事件中,状态迁移的动作会调用对象的方法

事件名([逗号分隔的参数列表])

时间事件(elapsed-time events),表明时间段过去,或某个特殊时间点的触发

通过时间表达式是否满足来表示事件,例如一个绝对时间点的列表,或者经过时间段过去后对象进入一个新的状态

用关键字when或after表示

信号事件(signal events),当给定对象收到某实时信号

表示接受一个对象发送的信号(信息)的事件,有可能引发状态迁移(状态改变)

事件名([逗号分隔的参数列表])

信号事件与调用事件的区别

信号事件是一个异步事件,调用事件一般是一个同步事件

UML状态图中的动作(Action)

动作是在状态内部或者状态间迁移时执行的原子操作

两种特殊的动作:入口动作(entry action)和出口动作(exit action)

entry动作:进入状态时执行得活动,格式如下:

‘entry’  ‘/’  action-expression

exit动作:退出状态时执行得活动,格式如下:

‘exit’  ‘/’  action-expression

(其中action-expression可以引用对象本身的属性和输入事件的参数)

10.6状态图精讲

UML态图中的组合状态(superstates)
可以通过状态嵌套的方式简化图表
一个组合状态可以包含一个或多个状态
组合状态可以实现从不同抽象层次去体现状态图
“OR”的组合状态:只能满足其一
“AND”的组合状态(并发状态):满足所有的子状态,AND的子状态会进一步嵌套为OR的子状态
组合状态的状态迁移
指向组合状态边界的状态迁移等价于指向该组合状态初态的迁移;
从组合状态边界转出的迁移等价于从该组合状态的终态发出迁移;
迁移可直接指向组合状态的子状态。
UML态图中的历史状态(History State)
历史状态是一种伪状态。当激活这个状态时,会保存从组合状态中退出时所处的子状态,用H表示;
当再次进入组合状态时,可直接进入到这个子状态,而不是再次从组合状态的初态开始;
H和Hao*的区别:
H只记住最外层的组合状态的历史;
H*可记住任何深度的组合状态的历史;


11.软件系统设计
11.1软件体系结构概念
小规模软件:算法的选择;数据结构的设计;数据库构造;
web搜索系统:信息采集模块;标引处理模块;信息检索模块;
软件体系结构概念 
软件体系结构(SoftWare Architecture)包括构成系统的设计元素的描述、设计元素之间的交互、设计元素的组合模式以及在这些模式中的约束。
包括:构件(一组基本的构成要素)、连接件(这些要素之间的连接关系)、物理分布(这些要素连接之后形成的拓扑结构)、约束(作用于这些要素或连接关系上的限制条件)、质量(性能)。
软件体系结构+构件+连接件+约束。
构件是具有某种功能的可复用的软件结构单元,表示系统中主要的计算元素和数据存储。
连接是构件间建立和维护行为关联与信息传递的途径。
机制:过程调用、中断、I/O、事件、进程、共享、同步、并发、消息、远程调用、动态连接、API等等。
协议:对过程调用来说:参数的个数和类型、参数排列次序;对信息传递来说:消息的格式。
连接件表示构件之间的交互并实现构件之间的连接。例如:管道(pipe)、过程调用(procedure cell)、事件广播(event broadcast)、客户机-服务器(client-server)、数据库连接(SQL)。
一般构件是软件功能设计和实现的承载体;连接件是负责完成构件之间信息交换和行为联系的专用软件。
软件体系结构设计目标:可重用性、可扩展性、可改变性、简单性、有效性。
软件体系结构的发展
面向过程的分析与设计》面向对象的分析与设计》基于构件的软件开发》面向服务的计算、面向服务的体系结构
细粒度=》粗粒度;IT技术=》商务过程;封闭=》开放。
风格、模式和框架
体系结构风格:用于描述某一特定应用领域中系统组织的惯用模式,反映了领域中众多系统所共有的结构和语义特性。
设计模式:描述了软件系统设计过程中常见问题的一些解决方案,通常是从大量的成功实践中总结出来的且被广泛公认的实践和知识。
软件框架:软件框架是由开发人员定制的应用系统的骨架,是整个或部分系统的可重用设计,由一组抽象构件实例间的交互方式组成。
框架和体系结构的关系:体系结构的呈现形式是一个设计规约,而框架是“半成品”的软件;
    体系结构的目的是指导软件系统的开发,而框架的目的是设计复用。
MVC框架的实现:前端有ANGULARJS、BACKBONE.JS,后端有Python的django框架。
框架和设计模式的关系:(1)框架给出的是整个应用的体系结构;而设计模式则给出了单一设计问题的解决方案,且可以在不同的应用程序或者框架中进行应用。(2)设计模式的目标是改善代码结构,提高程序的结构质量;框架强调的是设计的重用性和系统的可扩展性,以缩短开发周期,提高开发质量。
11.2软件设计原则
设计原则是系统分解和模块设计的基本标准,应用这些原则可以是代码更加灵活、易于维护和扩展。
包括:抽象、封装、模块化、层次化、复用。
抽象是关注事物中与问题相关部分而忽略其他无关部分的一种思考方法。
封装和信息隐藏是指每个软件单元对其他所有单元都隐藏自己的设计决策,各个单元的特性通过其外部可见的接口来描述。
模块化是在逻辑和物理上将整个系统分解成多个更小的部分,其实质是“分而治之”,即将一个复杂问题分解成若干简单问题,然后逐个解决。
系统分解的原则
目标:高内聚,低耦合。
内聚性是一个模块或子系统内部的依赖程度。
如果一个模块或子系统含有许多彼此相关的元素,并且它们执行类似任务,那么其内聚性比较高;如果一个模块或子系统含有许多彼此不相关的元素,其内聚性就比较低。
耦合性是两个模块或子系统之间依赖关系的强度。
如果两个模块或子系统是松散耦合的,二者相互独立,那么当其中一个发生变化时对另一个产生的影响就很小;如果两个模块或子系统是紧密耦合的,其中一个发生变化就可能对另一个产生较大影响。
层次化
分层(Layering)
每一层可以访问下层,不能访问上层
封闭式结构:每一层只能访问与其相邻的下一层
开放式结构:每一层还可以访问下面更低的层次
层数不应超过7+2层
划分(Partitioning)
系统被分解成相互对等的若干模块单元
每个模块之间依赖较少,可以独立运行
注意:模块单元增加了处理开销,过度分层或划分会增加复杂性。
例子:安卓操作系统层次结构

复用(reuse)是利用某些已开发的、对建立新系统有用的软件元素来生成新的软件系统,其好处在于提高生产效率,提高软件质量。
源代码复用:对构件库中的源代码=构件进行复用
软件体系结构复用:对已有的软件体系结构进行复用
框架复用:对特定领域中存在的一个公共体系结构及其构件进行复用
设计模式:通过为对象协作提供思想和范例来强调方法的复用
11.3软件体系结构风格
软件体系结构风格(Architectural Styles)是描述特定系统组织方式的惯用范例,强调了软件系统中通用的组织结构。
常见的体系结构风格

主程序-子程序
主程序-子程序风格是结构化程序设计额一种典型风格,从功能的观点设计系统,通过逐步分解和细化,形成整个系统的体系结构。
构件:主程序、子程序
连接器:调用-返回机制
拓扑结构:层次化结构
面向对象风格
系统被看作是对象的集合,每个对象都有一个它自己的功能集合;
数据及作用在数据上的操作被封装成抽象数据类型;
只通过接口与外界交互,内部的设计决策则被封装起来。
构件:类和对象
连接器:对象之间通过调用和消息传递实现交互
管道-过滤器风格
把系统任务分成若干连续的处理步骤,这些步骤由通过系统的数据流连接,一个步骤的输出时下一个步骤的输入。
以数据为中心的风格
举例:剪贴板是一个用来进行短时间的数据存储,并在文档/应用之间进行数据传递和交换的软件程序。
仓库体系结构(repository architecture)
是一种以数据为中心的体系结构,适合于数据由一个模块产生而由其他模块使用的情形。
举例:程序设计语言编辑器,基于数据库的系统结构
分层体系结构风格
例子:网络分层模型

客户机/服务器结构(client/server)
是一种分布式系统模型,作为服务器的子系统为其他客户机的子系统提供服务,作为客户机的子系统负责与用户的交互。
两层C/S结构
胖客户端模型:
服务器只负责数据的管理
客户机实现应用逻辑和用户的交互
胖客户端与瘦客户端
业务逻辑的划分比重:在客户端多一些还是在服务器端多一些?
胖客户端:客户端执行大部分的数据处理操作
瘦客户端:客户端具有很少或没有业务逻辑
三层C/S结构
表示层:包括所有与客户机交互的边界对象,如窗口、表单、网页等。
功能层(业务逻辑层):包括所有的控制和实体对象,实现应用程序的处理逻辑和规则。
数据层:实现对数据库的存储、查询和更新。
B/S结构
浏览器/服务器结构是三层C/S风格的一种实现方式。

集群结构
集群内各服务器上的内容保持一致(通过冗余提高可靠性与可用性)
集群内各服务器上的内容之和构成系统完整的功能/数据(通过分布式提高速度与并发性)
MVC结构
客户机-服务器结构
许多应用系统的用途都是从数据库中检索数据,并将其显示给用户。
在用户更改数据之后,系统在将更新内容存储到数据存储中。
因为关键的信息流发生在数据存储和用户界面之间,所以一般倾向于将这两部分捆绑在一起,以减少编码量并提高应用程序性         能。
模型-视图-控制器(MVC)结构将应用程序的数据模型、业务逻辑和用户界面分别放在独立构件中,这样对用户界面的修改不会对数据模型/业务逻辑造成太大影响。
模型(model):封装应用程序状态、响应状态查询、应用程序功能、通知视图改变;
视图(view):解释模型、模型更新请求、发送用户输入给控制器、允许控制器选择视图;
控制器(controller):定义应用程序行为、用户动作映射成模型更新、选择响应的视图;
事件风格




11.4软件设计过程

11.5web系统架构设计

11.6数据库选择策略

















0 0