2. 软件建设:视图之间的转换
软件构建中的转换类型
空集->代码
–编程/编码 (ADT/OOP) -审查、静态分析/检查
代码->组件
–设计(ADT/OOP;可重用性;可维护性)
-构建:编译、静态链接、打包、安装等
构建阶段->运行阶段
-安装/部署 –调试、单元/集成测试(健壮性和正确性)
某一时刻->时段
–版本控制 -加载、动态链接、执行(转储、分析、日志记录)
-并发线程
3.软件系统的质量属性
外部和内部质量因素
外部质量因素:诸如速度或易用性之类的质量,其在软件产品中的存在或不存在可能被其用户检测到。
适用于软件产品的其他品质,例如模块化或可读性,是内部因素,只有有权访问实际软件文本的开发人员才能感知。
最后,只有外部因素才影响软件真实的效果。
但实现这些外部因素的关键在于内部因素:为了让用户享受可见的品质,设计者和实施者必须应用内部技术来确保内部隐藏的品质。
外部质量因素影响用户,而内部质量因素影响软件本身和它的开发者;但是外部质量取决于内部质量。
3.1外部质量因素
外部因素1: 正确性Correctness
确保正确性的方法:测试和调试
经过测试和调试可以发现不正确,消除不正确。(对应第12章——健壮性)
防御性编程,例如typing和assertions;在写程序的时候就确保程序的正确性
旨在帮助构建从一开始就正确的软件 – 而不是将其调试为正确的。
(也对应12章的健壮性)
形式化方法:“检查”、“保证”和“确保”,通过这些形式化的验证发现问题。
需要使用正式程序规范和验证的数学技术(形式语言,对应研究生课程)
外部因素2: 健壮性Robustness
健壮性是软件系统对异常情况做出适当反应的能力。
-健壮性是对正确性的补充。
-正确性解决了系统在其规范涵盖的情况下的行为,正确性要求软件的行为需要严格符合规约中定义的行为。
-而健壮性则表征了如果软件出现了在这个规范之外的情况时发生什么;在出现规约定义之外的情形的时候,软件需要做出恰当的反应。
健壮性是为了确保如果确实出现这种情况,系统不会导致灾难性事件; 它应该产生适当的错误消息,干净地终止其执行,或者进入所谓的“优雅降级”模式。
所以健壮性的要求就是,出现异常时候不要直接“崩溃”,而是干一些别的事情。
鲁棒性与“异常情况”有关,这意味着正常和异常情况的概念始终与某个规范相关,需要注意的是,这里的“正常”normal和“异常”abnormal是我们主观定义的,不是指那种客观情况。
-异常情况只是规范(specification)未涵盖的情况。
-如果我们扩大spec规范集,过去不正常的情况就会变得正常——即使它们对应于我们不希望发生的错误用户输入等事件。
这个意义上的“正常”并不意味着“理想情况”,而只是“在软件设计中有所计划的”。
尽管一开始将错误的输入称为正常情况似乎有些矛盾,但任何其他方法都必须依赖于主观标准,而这是毫无用处的。
(对应后续知识异常处理->第12章)
也就是说,任何我们预料到的可能出现的错误输入,一旦我们为它专门设计了处理方法,这种输入已经被我们主观的预测与编程行为给纳入我们的规范specification的范围内了!我们要求的健壮性,是面对规范外的输入,不能是我们预料得到的也能妥善处理!
外部因素3: 可扩展性Extendibility
可扩展性(Extendibility)是使软件产品适应规范变化的容易程度。它代表了我们对软件的规约进行修改的难易程度;
对可扩展性来说软件规模是一个难题。软件规模越大,扩展起来就越不容易。
-对于小程序来说,改变通常不是一个困难的问题; 但是随着软件变得越来越大,它变得越来越难以适应。
-大型软件系统通常将其组成部分视为一个巨大的纸牌屋,其中任何一个元素都可能导致整个纸牌屋发生坍塌。
我们需要软件具有可扩展性,因为所有软件的基础都是一些人类现象,而它们都是变化无常的。所以我们扩展软件的原因是为了适应变化。
传统方法没有充分考虑变化,而是依赖于软件生命周期的理想视图,其中初始分析阶段冻结需求,其余过程致力于设计和构建解决方案。
两个原则对于提高可扩展性至关重要:
-设计简单:简单的架构总是比复杂的架构更容易适应变化。(在设计架构的时候采取简约主义设计)
-去中心化:模块的自主性越强,一个简单的更改仅影响一个模块或少数模块的可能性就越高,而不是触发整个系统的更改的连锁反应。
(分离主义设计)
(对应后续知识->章节ADT和OOP)
外部因素4: 可复用性Reusability
可复用性(Reusability)是软件元素为构建许多不同的应用程序服务的能力。我们开发出一个软件的模块,经过这一次开发,我们可以在之后的软件种多次复用。
对可重用性的需求来自对软件系统通常遵循相似模式的观察。 应该可以利用这种共性,避免对以前遇到的问题重新发明解决方案。所以我们需要发现不同软件之间的共性。
-可重用的软件元素将适用于许多不同的开发。
–不要重复自己干过的活!Don’t Repeat Yourself!(DRY原则)
复读机是吧
–不要重新发明轮子
(对应后续知识->设计/复用)
外部因素5: 兼容性Compatibility
兼容性(Compatibility)是指将软件元素与其他元素结合起来的容易程度。具有兼容性的软件构件可以使不同的软件系统之间相互可以容易地集成;
兼容性很重要,因为我们不是在真空中开发软件元素:它们需要相互交互。
但他们经常难以互动,因为他们对世界其他地方做出了相互矛盾的假设。
一个例子是许多操作系统支持的各种不兼容的文件格式。 只有在文件格式兼容的情况下,程序才能直接使用另一个结果作为输入。
兼容性的关键在于设计的同构性,以及就程序间通信的标准化约定达成一致。兼容性的关键是标准化,尤其是标准协议。
有如下几种实现方法:
- 标准化的数据结构,如在 Lisp 系统中,所有数据和程序都由二叉树(在 Lisp 中称为列表)表示。
- 标准化的用户界面,如在各种版本的 Windows、OS/2 和 MacOS 上,所有工具都依赖于与用户通信的单一范例,基于窗口、图标等标准组件。
通过为软件操作的所有重要实体定义标准化的访问协议,可以获得更通用的解决方案。
外部因素6: 性能 Efficiency
性能是软件系统对硬件资源的要求尽可能少的能力,例如处理器时间、内部和外部存储器占用的空间、通信设备中使用的带宽。
如果软件不正确,效率并不重要(“不要担心它有多快,除非它也是正确的”)。在具有正确性之前,多么优秀的性能都毫无意义!!
对性能的关注必须与其他目标(例如可扩展性和可重用性)相平衡,性能要与其他的质量属性进行折中。
极端优化使软件过于专业化,以至于软件不再适应变化和复用。
计算正确性的抽象概念与通过优化实现性能的具体实现:算法、I/O、内存管理等。
外部因素7: 可移植性 Portability
可移植性是将软件产品转移到各种硬件和软件环境的容易程度。可移植性可以让软件方便地在不同的技术环境之间移植。
可移植性不仅解决了物理硬件的变化,而且更普遍地解决了硬件-软件机器的变化,我们真正编程的机器,包括操作系统、窗口系统(这里不是指Windows)(如果适用的话)和其他基本工具。
外部因素8: 易用性 Ease of use
易用性(Easy of use) 是不同背景和资格的人学习使用软件产品并将其应用于解决问题的难易程度。具有易用性的软件,需要容易学、容易安装、容易操作、容易监控。
如何为新手用户提供详细的指导和解释,而不会打扰只想开始业务的专家用户。(给新用户详细的指南,大佬直接跳过新手教程)
–结构简单
一个设计良好的系统,根据一个清晰、深思熟虑的结构构建,往往比一个凌乱的系统更容易学习和使用。
–了解用户
重要的是,一个好的设计师必须努力理解系统的预期用户 区。
外部因素9: 功能性 Functionality
功能性代表了一个软件系统提供了多少种可能性,提供了多大的可能性空间。
特征主义(通常是“爬行特征主义”)是程序设计中一种不适宜的趋
势,即软件开发者增加越来越多的功能,企图跟上竞争,其结果是程
序极为复杂、不灵活、占用过多的磁盘空间。
更容易的问题是添加新功能可能导致一致性的丧失,从而影响其易用性。 众所周知,用户抱怨产品新版本的所有“花里胡哨”使它变得非常复杂。
更困难的问题是避免过于关注特征而忘记其他品质(对整体品质的忽视)。
奥斯蒙德曲线
Osmond 建议(颜色曲线)在 OO 开发的质量增强技术的帮助下,在整个项目中,在除了功能之外的所有方面保持质量水平不变。
我们只是不会在可靠性、可扩展性等方面妥协:我们拒绝继续使用新功能,直到我们对现有的功能感到满意为止。
(对应后续知识->灵活,SCM)
从考虑所有质量因素的一小部分关键特性开始。在开发过程中逐渐添加更多特性,并保证与关键特性相同的质量。每增加一点功能,都确保其他质量属性不受损失。
外部因素10: 及时性 Timeliness
及时性(Timeliness)是软件系统在用户需要时或之前发布的能力。
一个伟大的软件产品出现得太晚可能会完全错过它的目标。
一定在DDL之前把它给肝出来呀!
外部因素10++: 其它的品质
可验证性(Verifiability)是准备验收程序的容易程度,尤其是测试数据,以及在验证和操作阶段检测故障并跟踪错误的程序。
完整性(Integrity)是软件系统保护其各种组件(程序、数据)免受未经授权的访问和修改的能力。
可修复性(Repairability)是促进缺陷修复的能力。
经济性(Economy),及时性的搭档,是系统在其分配的预算内或以下完成的能力。
3.2内部质量因素
复杂性是几乎所有外部质量因素的敌人!内部质量因素通常用作外部质量因素的部分量度。
-源代码相关因素,例如代码行 (LOC)、圈复杂度等
-与架构相关的因素,例如耦合、内聚等
-可读性 -易懂性/可理解性
-清晰度/整洁度 -大小
3.3质量属性之间的折中
如何在不引入各种保护措施的情况下获得完整性这将不可避免地妨碍易用性)
经济性似乎经常与功能性起冲突。
最佳性能需要完美适应特定的硬件和软件环境,这与可移植性相反,并且完美适应规范,其中可重用性推动解决比最初给出的问题更具有普遍性的问题。
及时性压力可能会诱使我们使用“快速应用程序开发”技术,其结果可能无法获得太多可扩展性。
完整性易用性 经济性功能性
性能可移植性 性能可重用性
经济性可重用性 及时性可扩展性
OOP 如何提高质量
§ 正确性:封装、去中心化 § 健壮性:封装、错误处理
§ 可扩展性:封装、信息隐藏
§ 可重用性:模块化、组件、模型、模式
§ 兼容性:标准化模块和接口 § 可移植性:信息隐藏、抽象
§ 易用性:GUI组件、框架 § 性能:可重复使用的组件
§ 时效性:建模、重用 § 经济性:再利用
§ 功能性:可扩展性
4. 软件建设的五个关键质量目标
优雅(Elegant,埃莉根to!!)漂亮的代码->容易理解,易懂;
(代码规格Specification)代码要容易理解,通过统一变量/方法的命名标准、代码的风格、注释、包组织结构、必要时重构代码等方式让代码尽可能的容易理解。
为了复用设计/利用复用设计->开发成本低(复用性Reusability)
ADT/OOP、接口、继承(Overload、Override)、多态、泛型、框架等技术可用于提高代码的可复用性。
低复杂度->快速适应变化,易于扩展(可维护性Maintainability)当复杂度较低的时候,代码就容易被扩展新的功能,所以要高内聚低耦合,遵从SOLID原则、OO设计模式、使用VCS控制代码版本
健壮性与正确性->远离bug,不易出错(健壮性/正确性)使用测试驱动的开发、异常处理、Assertion机制、防御式编程等技术保证程序的健壮性和正确性。
性能和效率->高效运行(ADT 和 OOP 章)使用设计模式、并行/多线程等技术提升性能。
可复用性
可维护性和适应性
健壮性
内容小结
描述软件系统的三个维度:
- 按阶段:构建和运行时视图
- 按动态:时刻和时段视图
- 按级别:代码和组件视图
每个视图的元素、关系和模型
软件构建:视图之间的转换
空集->代码 代码->组件
构建阶段->运行阶段 某一时刻->时段
软件系统的质量属性
- 外部与内部质量因素
- 重要的外部质量因素
- 质量因素之间的折中
软件建设的五个关键质量目标
– 易于理解:优雅漂亮的代码/可理解性
– 快速适应变化:可维护性和适应性
– 开发成本低:设计/重用:可重用性
– 远离错误:健壮性
– 高效运行:性能
对应的本课程要学习的构建技术(按五个关键质量目标的方向分类)
在这一个章节,我们简单地了解了一个优秀的软件需要具备的外部质量因素和内部质量因素;我们理解到不能单纯地追求某一种特点而去做优化,而是在各种质量方面作出折中。
在这些质量中我们总结出我们五个关键的质量指标,并且了解了在这方面我们将来要学习的知识模块。接下来就让我们正式走上软件构造的学习罢(喜)
文章知识点与官方知识档案匹配,可进一步学习相关知识 络技能树跨区域 络的通信学习 络层的作用22197 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!