2019春软件构造知识点总结 第6,7章

▪ 可维护性的常见度量指标
易于纠正错误和提升性能
易于增加功能
易于改变
适应用户个性化需求
可以高效,轻松地监控和维护软件系统
发布后,软件受支持的程度

Cyclomatic Complexity(代码结构的复杂性)
Lines of Code(代码行数)
Halstead Volume(运算符和操作数的数目)
Maintainability Index(可维护性指数)
Depth of Inheritance(继承深度)
Class Coupling(类耦合程度)
Unit test coverage(单元测试覆盖率)

▪ 聚合度与耦合度
模块化编程
设计的目标是将系统划分为模块,并以下列方式在组件之间分配责任:

  • 模块内的高内聚力
  • 模块之间的松耦合
    模块化降低了程序员在任何时候必须处理的总复杂性,假设:
  • 将功能分配给远离的模块,将相似的功能组合在一起(关注点分离)
  • 模块之间有小而简单,定义良好的接口(信息隐藏)
    内聚和耦合的原理可能是评估设计可维护性的最重要的设计原则

模块化设计的五个规则
Direct Mapping (直接映射)
Few Interfaces (尽可能少的接口)
Small Interfaces (尽可能小的接口)
Explicit Interfaces (显式接口)
Information Hiding (信息隐藏)

耦合
耦合是模块之间依赖性的度量。
如果一个模块中的更改可能需要更改另一个模块,则两个模块之间存在依赖关系。
模块之间的耦合程度由以下因素确定:
接口数量,接口复杂度。

凝聚
凝聚力衡量模块的功能或职责的相关程度。
如果模块的所有元素都朝着相同的目标努力,则模块具有高内聚力。

内聚和耦合
最佳设计在模块内具有高内聚力(也称为强内聚力),在模块之间具有低耦合(也称为弱耦合)。
耦合和凝聚力是权衡取舍
当耦合高时,内聚力往往较低,反之亦然。

▪ SOLID
(SRP) The Single Responsibility Principle 单一责任原则
(OCP) The Open-Closed Principle 开放封闭原则
(LSP) The Liskov Substitution Principle Liskov替换原则
(ISP) The Interface Segregation Principle 接口隔离原则
(DIP) The Dependency Inversion Principle 依赖转置原则

▪ 设计模式:factory method、
abstract factory、builder、
bridge、proxy、composite、
observer/observable、visitor、
state、memento
创作模式

  • 工厂方法模式创建对象而不指定要创建的确切类。
  • 抽象工厂模式将具有共同主题的对象工厂分组。
  • 构建器模式通过分离构造和表示来构造复杂对象。
    结构模式
  • Bridge将抽象与其实现分离,以便两者可以独立变化。
  • Proxy为另一个对象提供占位符,以控制访问,降低成本并降低复杂性。
  • Composite组合零个或多个类似对象,以便可以将它们作为一个对象进行操作。
    行为模式
  • Observer是一种发布/订阅模式,它允许许多观察者对象查看事件。
  • Mediator允许类之间的松散耦合,因为它是唯一具有详细方法知识的类。
  • 访问者通过将方法的层次结构移动到一个对象中来将算法与对象结构分离。
  • 责任链将命令委托给一系列处理对象。
  • Command创建封装操作和参数的对象。

▪ 语法、正则表达式
终端:语法中的文字字符串
▪为了描述一串符号,无论它们是字节,字符还是从固定集合中绘制的其他类型的符号,我们使用称为语法的紧凑表示。
▪语法定义一组字符串。

  • 例如,URL的语法将指定作为HTTP协议中合法URL的字符串集。
    ▪语法中的文字字符串称为终端。
    终结符/终止符
  • 它们被称为终端,因为它们是表示字符串结构的解析树的叶子。
  • 他们没有任何孩子,也无法进一步扩展。
  • 我们通常用引号编写终端,比如’http’或’:’。

语法中的非终结与制作
▪语法由一组产品描述(产生式),其中每个产品定义一个非终结符(非终结符)。

  • 非终结符就像一个代表一组字符串的变量,而生成作为该变量的定义,就其他变量(非终结符号),运算符和常量(终端)而言。
  • 非终结符是表示字符串的树的内部节点。
    ▪语法生成具有形式
  • nonterminal :: =终端,非终结符和运算符的表达式
    ▪语法的一个非终结符被指定为根。
  • 语法识别的字符串集是与根非终结符匹配的字符串集。
  • 这个非终结符通常称为root或start。

符号:
(空格)连接 跟随
(*) 重复 0次或多次
| 合并 或
? 可选 0次或一次
(+)一次或多次
[abc] a|b|c
[(^)abc]除abc之外的或

A regular grammar正则文法
对root对应的产生式右侧,替换其中所有root之外的非终结符(用非终结符的右侧),如果最终可以得到只有终结符和操作符构成的产生式,则为正则语法

▪ 健壮性和正确性
Robustness(鲁棒性/健壮性):系统或组件在存在无效输入或压力环境条件时可以正确运行的程度
Correctness(正确性):正确实现规格说明的能力

提高稳健性和正确性的步骤
步骤0:使用稳健性和正确性目标编程代码(断言,防御性编程,代码审查,形式验证等)
步骤1:观察故障症状(内存转储,堆栈跟踪,执行日志,测试)
步骤2:识别潜在故障(错误定位,调试)
步骤3:修复错误(代码修订)

▪ Throwable
Java编程语言中,异常对象始终是从Throwable派生的类的实例。

▪ Runtime异常、其他异常
RuntimeException和其他异常
在进行Java编程时,请关注异常层次结构。
Exception层次结构也分为两个分支:从RuntimeException派生的异常和不派生的异常。
一般规则:

  • 发生RuntimeException是因为您发生了编程错误。
  • 发生任何其他异常是因为您的其他好程序发生了一件坏事,例如I / O错误。

▪ Checked异常、Unchecked异常
已检查/未检查的例外情况
未经检查的异常:编程错误,其他不可恢复的失败(错误+ RuntimeException)
不要求必须捕获处理
检查异常:每个呼叫者都应该注意并处理的错误
要求必须捕获处理,compiler会进行检查

Checked异常的处理机制:
检查异常处理操作
异常处理中使用了五个关键字:try,catch,finally,throws和throw。
Java的异常处理包括三个操作:

  • 声明异常(抛出)
  • 抛出异常(抛出)
  • 捕获异常(尝试,捕获,最后)

一个方法必须声明它可能抛出的所有checked异常。
Compiler会检查是否所有checked异常都被正确声明了。
Unchecked异常不需要处理(要么无法处理,要么不应该发生)。

▪ 断言的作用、应用场合
断言用于在运行时检查代码正确性

  • 当断言为真时,这意味着一切都按预期运行。
  • 当它为假时,表示它已在代码中检测到意外错误。

断言通常需要两个参数

  • 一个布尔表达式,描述假设为真的假设
  • 如果为假则显示消息。
    ▪Java语言有一个关键字断言。 有两种形式:
  • 断言条件;
  • 断言条件:表达;
  • 如果布尔表达式的计算结果为false,则两个语句都会评估条件并抛出AssertionError。
  • 第二种方式允许提供错误信息提示

作用:
测试不变性是否保持,同时起到了文档说明作用
验证程序员的理解
快速发现bug
增加程序无错误的信心
断言将黑盒测试变为白盒测试

▪ 调试的基本过程和方法
重现问题→找到原因→解决问题,避免引入回归性错误→反思,总结经验
科学的调试方法
以下是使用科学方法时的步骤:

  • 1.通过可重复的实验收集数据。
  • 2.形成一个假设,说明相关数据。
  • 3.设计一个实验来证明或反驳这一假设。
  • 4.证明或反驳这一假设。
  • 5.根据需要重复。
    ▪ 黑盒测试用例的设计
    Black-box测试将软件视为“黑匣子”,在不了解内部实现的情况下检查功能,而无需查看源代码。
    黑盒测试尝试查找以下类别中的错误:
  • (1)功能不正确或缺失,
  • (2)界面错误,
  • (3)数据结构或外部数据库访问错误,
  • (4)行为或性能错误,以及
  • (5)初始化和终止错误。

黑盒测试的测试用例是围绕规范和需求构建的,即应用程序应该做什么。

▪ 以注释的形式撰写测试策略

▪ JUnit测试用例写法
什么是测试用例?
测试用例,是一组测试输入,执行条件和预期结果。 即,测试用例= {测试输入+执行条件+预期结果}
输入+执行条件+期望结果

  • 针对特定目标开发测试用例,例如执行特定程序路径或验证是否符合特定要求。
    为特定目标设计
  • 测试用例可能只是您询问该程序的问题。 运行测试的关键是获取信息,例如程序是否通过测试。
  • 测试用例是质量保证的基石,而它们的开发是为了验证产品的质量和行为。
  • 例如,测试用例:{2,4},{0,0},{ - 2,4}用于程序y = x ^ 2。

流行的单元测试框架:JUnit
JUnit是一种广泛采用的Java编程语言单元测试框架。
JUnit在测试驱动开发的开发中非常重要,并且是一系列单元测试框架之一,统称为xUnit,源自SUnit。
在每个测试方法前面使用@Test标注指明
单元测试方法通常包含对正在测试的模块的一个或多个调用,然后使用assertEquals,assertTrue和assertFalse等断言方法检查结果。

请注意,assertEquals参数的顺序很重要。

  • 第一个参数应该是测试想要看到的预期结果,通常是常量。
  • 第二个参数是实际结果,代码实际执行的操作。
  • JUnit支持的所有断言都遵循此顺序:预期第一个,实际第二个。参数的顺序

▪ 测试覆盖度
代码覆盖率
白盒测试应考虑测试用例的代码覆盖率,以用于程序的内部逻辑。
代码覆盖率是用来描述特定测试运行时程序的源代码执行程度的度量。
具有高代码覆盖率的程序(以百分比衡量)在测试期间执行了更多的源代码,这表明与代码覆盖率低的程序相比,它包含未检测到的软件错误的可能性更低。
在执行测试中,子程序和被调用语句的百分是常用的测量标准

代码覆盖率
基本覆盖标准

  • 功能覆盖 - 是否已调用程序中的每个功能(或子程序)?
  • 声明范围 - 程序中的每个声明是否已执行?
  • 决策或分支覆盖 - 每个控制结构的每个分支(例如if和case语句)是否已执行? 例如,给定if语句,是否已执行true和false分支? 另一种说法是,程序中的每个边缘都被执行了吗?
  • 条件或谓词覆盖 - 每个布尔子表达式都被评估为true和false?
  • 条件/决策覆盖要求满足决策和条件覆盖。
  • 多条件覆盖要求测试每个决策中的所有条件组合。
  • 路径覆盖:每个可能的分支组合 - 通过程序的每个路径 - 由一些测试用例采取?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值