【08】2.4 软件开发方法

2.4.1  软件工程特性

1、软件工程的不成熟
软件设计是一种思维过程,而代码是固化的思维。

(1)方法学不成熟
建筑领域的方法比较稳定;
软件工程的方法学非常动态化和不成熟;
建筑工程对工作成果有一套行之有效的评估方法;
对程序员的工作成果进行定量评估时,都会以失败告终;
软件工程一直在寻找更好的设计方法。

(2)缺少通用构件
传统工程领域通常采用预先定制的部件来构建系统;
软件设计的模块往往用于特定领域。

(3)缺少度量技术
软件需求的复杂度目前只能依赖人工判断,不能进行精确度量。
软件质量和性能要求必须是可测试的。

不可测试要求,如:系统必须是可靠的”就是一句正确的废话。

可测试要求,如:“系统死机”必须不高于1次/年。

2、软件设计中的折中和妥协
软件不可能满足所有涉众群的需求。
折中是创建系统结构的主要原则,而妥协也是系统结构的重要属性。
涉众群各自的需求:
最终用户关心直观感受。如:界面友好,易用性,系统稳定,安全性等。
管理人员关注可管理性。如:监测工具,易恢复,模块可替换等。
开发人员关注可行性。如:清晰的系统需求,简单一致的设计方法等。
项目经理关注项目实施。如:项目追踪,计划实施,资源利用,可预见性等。
维护人员关注易理解性。如:软件一致性,充分和规范的文档,易修改性等。

3、程序中的的依赖
经常会发现程序在某些机器上可运行,换一台机器却不能运行。
原因:机器中缺少程序运行必要的库或库版本不一致。
如:Windows下的应用程序可能会缺少.DLL依赖库;
如:Python程序可能会出现缺少第三方依赖库等。
可以通过工具软件来分析程序所需要的依赖库或依赖包。

4、膨胀的软件
1989年,Word第1版为2.7万行代码,20年后增加到200万行。
人们戏称这些软件为“膨件”。
程序雍肿原因:
为了兼容性保留了大量的旧代码;
程序员不关注代码体积,就可以更快地完成软件开发;
图形用户界面意味着调用庞大的图形函数库;
更多的代码意味着软件更多的功能;
不同用户对软件的功能要求各不相同。

用户需求庞杂是因为软件的应用面太大了。


【例】1989年,Word第一版为2.7万行程序代码,20年后增加到200万行。

 

2.4.2  程序设计原则

1、程序设计的基本原则
(1)阅读和理解代码
程序员要具备阅读和理解其他人代码的能力。
程序员很少完全从零开始写代码。
Python编码规范PEP8推荐:
代码中一行不要超过79个字符;
一个函数不要超过30行代码;
一个类不要超过200行代码;
一个模块不要超过500行代码。

(2)保持清晰
程序代码不清晰容易产生Bug。
避免将表达式写得过于精炼,这会给维护人员带来工作量。
大多数情况下,清晰的代码和聪明的代码不可兼得。

(3)简单并不容易
最优雅的解决方案往往是最简单的。
简单并不容易,达到简单通常需要做很多的工作。

程序必须可读,然后可执行。 最基本的材料,不是语法和算法,而是控制大型软件系统的复杂性的方法。
      —— 哈罗德·阿贝尔森《计算机程序的构造和解释》

2、程序模块化设计原则
把大程序划分为若干子程序;每个模块继续划分为更小的子模块;
使软件具有一种层次性结构。
保持“功能独立”是模块化设计的基本原则。
模块化设计原则:
(1)模块可分解性。
(2)模块可组装性。
(3)模块可理解性。
(4)模块连续性。
(5)模块保护。

3、软件的复用
复用指利用现成的东西。
新系统中,大部分内容很成熟,只有小部分内容需要创新。
程序设计专家的口头禅:请不要再发明相同的车轮子了。
构造新软件系统时,直接使用已有的成熟构件。
一些基本构件经过反复的使用和验证,具有较高的质量。

如果有人基本上做出了你想要做的东西,你就没必要自己写一个新程序。就算你非写不可,也请尽可能多地利用现有的代码。
            —— Richard Hill

2.4.3  程序异常原因

1. 错误和异常
操作失败是所有程序都会遇到的情况。
错误和异常存在区别。
错误可以由程序预设,错误也可以被程序捕获和处理。
异常是一个没有被程序处理的错误。

如果事情可能出错,它就一定会出错。
     —— 墨菲定律

2. 程序异常的原因

3. 程序错误类型
(1)语法错误
常见语法错误:
采用中文符号;
括号不匹配;
变量没有定义;
缺少xxx等。
发生语法错误时会中断执行过程。

当你想在你的代码中找到一个错误时,这很难;
当你认为你的代码不会有错误时,这就更难了。
         ——史蒂夫·麦克康奈尔《代码大全》

(2)语义错误
变量声明错误
作用域错误
数据存储区的溢出等。

(3)逻辑错误
程序运行正常,但得不到期望的结果。
如:要求循环100次,应当写成:for i in range(0, 100);
如果写成了:for i in range(1, 100),程序实际只做了99次循环。

在我所有的程序错误中,80%是语法错误,剩下20%里,80%是简单的逻辑错误,在剩下4%里,80%是指针错误,只有余下的0.8%才是困难的问题。
        —— Marc Donner

2.4.4  软件测试方法

1、软件测试的计算思维

定义:在规定条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。

有人认为:“软件测试是证明软件不存在错误的过程”。
这个目标实际上无法达到。
黑客会用你做梦也想不到的方式来攻击你的程序。

迪科斯彻:“测试只能表明软件有错误,而不能表明软件没有错误”。
现在没有发现问题并不等于问题不存在。

2、软件质量衡量指标
质量特性:功能性、可靠性、易用性、效率、维护性、可移植性。
衡量软件质量的可操作性指标:
(1)源代码行数
主要体现了软件的规模。
代码行数不能用来评估程序员的工作效率,否则会产生重复的程序代码。
(2)代码Bug数

(3)代码测试覆盖率
程序中源代码被测试的比例和程度。

(4)设计约束
如:类或方法的代码长度;
如:一个类中方法或属性的个数;
如:方法或函数中参数的个数;
如:代码中的“魔术数字”;
如:注释行占程序代码行的比例等。

调试一个初次见到的代码比重写代码要困难两倍。因此,按照定义,如果你写代码非常巧妙,那么没有人足够聪明来调试它。
      —— 布莱恩·克尼根《编程风格的元素》

(5)圈复杂度
圈复杂度是代码复杂程度的衡量标准。
圈复杂度=“判定条件”的数量,
计算公式为:V(G)=判定节点数+1。
圈复杂度可用工具软件自动计算。
圈复杂度数量上表现为独立路径的条数。
圈复杂度大说明程序代码可能质量低,而且难于测试和维护。

控制复杂度是计算机编程的本质。
         —— 布莱恩·克尼根
 

【例】圈复杂度。

3、白盒测试技术

白盒测试是对软件内部结构进行测试,但不需要测试软件的功能。
白盒测试以软件开发人员为主。
白盒测试的方法:
基本路径测试、逻辑覆盖、代码检查、静态结构分析、符号测试、程序变异等。

路径测试的缺陷:
路径的数量是分支数量的几何级数。
由于数据之间的相互关系,有些路径不可能被测试到。

【例】程序模块的基本路径测试。

【例】基本路径测试。
 

【例】降低程序圈复杂度。

 

白盒测试的缺陷
软件测试的致命缺陷是测试的不完备性。
白盒测试是一种穷举测试方法,而程序的独立路径可能是一个天文数字。
即使每条路径都测试了,程序仍然可能存在问题。

4、黑盒测试技术
黑盒测试也称为功能测试。
黑盒测试不考虑程序的内部结构。

(1)黑盒测试方法
测试用例:为特定目的设计的一组测试输入、执行条件、预期结果。
测试用例包括:
等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法等。

(2)等价类黑盒测试方法
等价类就是测试数据的典型值或极限值。
把全部输入数据合理划分为若干等价类;
在每个等价类中取一个典型值作为测试的输入条件;
用少量代表性的测试数据取得较好的测试结果。

学生成绩测试中的有效等价类和无效等价类:

(3)边界值黑盒测试方法
常见边界值:
学生成绩的0、100;
屏幕光标的最左上、最右下位置;
报表的第一行和最后一行;
数组元素的第一个和最后一个;
循环的第0次、第1次和倒数第2次、最后一次;
最大/最小、首位/末位、上/下、最快/最慢、最高/最低、最短/最长、空/满等。

(4)黑盒测试的缺点
黑盒测试的输入可能有无穷多个;
不仅要测试所有合法的输入;
对不合法但可能的输入也需要进行测试。

(5)自动化测试
自动化测试在用户界面测试、性能测试、功能测试中应用较多。
自动化测试通过执行测试脚本来实现测试过程的自动化。
手工测试强在测试业务逻辑,自动化测试强在测试程序结构。

 

2.4.5  软件开发模型

软件开发工作:
问题的描述;
软件功能需求分析;
设计规格说明;
编制程序代码;
测试程序;
软件交付使用。

1、瀑布模型
核心思想:将开发划分为一些基本活动;
如:制定计划,需求分析,软件设计,程序编写,程序测试,软件运行和维护等。

瀑布模型有利于大型软件开发过程中人员的组织和管理。
缺陷:
开发成果未完成时,用户无法看到软件的效果,这样增加了风险。
前期末发现的错误,在后面可能会扩散,造成整个软件开发失败。
软件需求分析阶段,完全确定用户的所有需求较为困难。

2、增量模型
第一个增量是产品的核心,它实现系统的基本需求;
客户对每一个增量进行评估,作为下一个增量的改进意见;
每个增量发布后不断重复,直到产生最终的产品。
优点:
增量能够有计划地管理技术风险。
缺点:
如果增量之间的关系没有处理好,会导致系统的重新建立。

【例】增量模型。

 

3、敏捷开发方法
敏捷开发方法:Scrum;极限编程;特征驱动;看板等。
敏捷方法特征:
强调适应性而非预测性;
强调以人为中心而不是以流程为中心;
强调对变化的适应;
强调程序员与业务专家之间的紧密协作;
强调面对面的沟通;
强调频繁交付新的软件版本,很好地适应需求变化;
注重软件开发中人的作用。

为人而设计,而不是系统:开发者常常因技术而使设计误入歧途。绝不要忘记设计的最终目标,那就是帮助人们完成工作。
        —— 敏捷开发原则
 

敏捷开发基本原则:
(1)最优先的是尽早的、持续的交付有价值的软件,使客户满意。
(2)即使在软件开发后期,也欢迎改变用户需求。
(3)软件交付的时间间隔越短越好。
(4)要求尽可能少的文档,最基本的文档是程序代码。
(5)业务人员和开发人员必须天天在一起工作。
(6)程序员不能通过文档交流,应当面对面的实时交流。
(7)每隔一定时间,团队需要对开发工作进行反省,并相应地调整自己的行为。
(8)确定开发中的瓶径,对于瓶径处的工作应该尽量加快。
 

敏捷开发的局限性:
不适宜那些需求不明确的项目;
不适宜优先权不清楚的项目;
不适宜在“较快、较便宜、较优”中不能确定优先级的项目。

 

 返回主目录

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值