软件构造课程复习笔记

软件构造课程重点

Focus of Software Construction Course

本文按照哈尔滨工业大学软件构造课程的授课顺序展开,
可以帮助读者快速系统地了解高校软件构造课程的授课脉络,
但不适合作为全面系统性学习的主要参考资料。

文章目录

1.1 软件构造中的多维视图

1.1 Multi-Dimensional Views of Software Construction

软件构造的三维视图
不同视图之间的转换
 

1.2 软件构造的质量目标

1.2 Quality Objectives of Software Construction

  1. 外部质量因素影响用户
    External quality factors affect users
  2. 内部质量因素影响软件本身和它的开发者
    Internal quality factors affect the software itself and its developers
  3. 外部质量取决于内部质量
    External quality results from internal quality

1.2.1 外部指标

1.2.1 External quality factors

软件质量的几个外部指标

1.2.2 内部指标

1.2.2 Internal quality factors

软件质量的几个内部指标

1.2.3 折中

1.2.3 Tradeoff between quality properties

  1. 虽然需要折中,但“正确性”绝不能与其他质量因素折中
  2. 最重要的几个质量因素
    Correctnessand robustness: reliability
    Extendibilityand reusability: modularity
     

6.5 软件测试与测试优先的编程

6.5 Testing and Test-First Programming

6.5.1 初步了解各类测试

6.5.1 Introduction to various software tests

几种软件测试
单元测试:只测试单个模块(方法、类)
集成测试:多个模块
系统测试:非软件的东西集成进来,软硬件的测试
验收测试:甲方根据合同要求测试
回归测试:一旦程序有改动(改了bug),重新(头)执行之前的所有测试

静态分析:在buildtime发生,人眼去看代码
Testing:在runtime发生,为了发现错误
debugging:在runtime发生,为了找到在哪里错了

黑盒测试:不考虑内部代码,只测试程序外部表现出来的行为(只由spec测试功能)
白盒测试:考虑了程序内部代码的结构

为什么不能做到完备性测试?
不可能把所有输入(路径)都尝试一遍,这就需要折中

6.5.2 好的测试用例

6.5.2 Good test case

好的测试用例的特征
好的测试用例的特性
Choosing Test Cases by Equivalence Partitioning
Include Boundaries in the Partition
代码覆盖度
显式记录下你的测试特性

 

2.1 软件生命周期与配置管理

2.1 Software Lifecycle and Configuration Management

从无到有,从有到好

2.1.1 传统软件开发过程模型

2.1.1 Traditional Software Process Models

Traditional software process models

  1. 瀑布过程:线性推进,阶段划分清楚,整体推进,无迭代,管理简单,无法适应需求增加/变化;
  2. 增量过程:线性推进,增量式(多个瀑布的串行),无迭代,比较容易适应需求的增加;
  3. V字模型:for verification and validation
  4. 原型(迭代):在原型上持续不断的迭代发现用户变化的需求。
    迭代:开发出来之后由用户试用/评审,发现问题反馈给开发者,开发者修改原有的实现,继续交给用户评审。
    循环往复这个过程,直到用户满意为止。时间代价高,但开发质量也高。
  5. 螺旋(迭代):非常复杂的过程,多轮迭代基本遵循瀑布模式。
    每轮迭代有明确的目标,遵循“原型”过程,进行严格的风险分析,方可进入下一轮迭代

2.1.2 敏捷开发

2.1.2 Agile Development

敏捷开发:通过快速迭代和小规模的持续改进,以快速适应变化。
Agile = 增量+ 迭代
每次迭代处理一个小规模增量

2.1.3 软件配置管理(SCM)与版本控制系统(VCS)

2.1.3 Software Configuration Management (SCM)and Version Control System (VCS)

软件配置管理(SCM):追踪和控制软件的变化。
SCM practices include revision control and the establishment of baselines.

软件配置项:软件中发生变化的基本单元(例如:文件)
Software Configuration Item (SCI): the fundamental structural unit of SCM.

基线:软件持续变化过程中的“稳定时刻”(例如:对外发布的版本)
版本控制与基线
配置管理数据库(CMDB):存储软件的各配置项随时间发生变化的信息 + 基线。
配置管理数据库CMDB
版本:为软件的任一特定时刻(Moment)的形态指派一个唯一的编号,作为“身份标识”。
本地 / 集中 / 分布式 版本控制系统

2.1.4 软件配置管理工具:以Git为例

2.1.4 Git as an example of SCM tool

git
Git
Object Graph
nodes
changes
branches
branches

 

2.2 软件构造的过程、系统和工具

2.2 Process, Systems, and Tools of Software Construction

Summary of Lecture 2.2

2.2.1 软件构造的一般过程

2.2.1 General process of software construction

General process of software construction

  1. Programming
    Construction Languages
    Programming tools
  2. Review and static code analysis
  3. Dynamic code analysis / Profiling
    动态分析:要执行程序并观察现象、收集数据、分析不足
    Profiling:对代码的运行时状态和性能进行度量,发现代码中的潜在问题

Profiling(“program profiling”, “software profiling”) is a form of dynamic program analysis that measures the space (memory) or time complexity of a program, the usage of particular instructions, or the frequency and duration of function calls.
Dynamic code analysis / Profiling

  1. Debugging and Testing
  2. Refactoring
    重构:在不改变功能的前提下优化代码

Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
Incurs a short-term time/work cost to reap long-term benefits, and a long-term investment in the overall quality of your system.

Refactoring is:

  • restructuring (rearranging) code…
  • …in a series of small, semantics-preserving transformations…
  • …in order to make the code easier to maintain and modify

2.2.2 狭义的软件构建过程(Build)

2.2.2 Narrow-sense process of software construction (Build)

粗略理解build:build-time -> run-time
借助于工具,将软件构造各阶段的活动“自动化”(编译、打包、静态分析、测试、生成文档、部署…)尽可能脱离“手工作业”,提高构造效率
Typical BUILD scenarios
Continuous Integration

 

3.1 数据类型与类型检验

3.1 Data Type and Type Checking

3.1.1 数据类型

3.1.1 Data type in programming languages

Data Type
重载:同样的操作名可用于不同的数据类型
Overloading operators/operations: Some operations are overloaded in the sense that the same operation name is used for different types.

3.1.2 静态与动态数据类型检查

3.1.2 Static vs. Dynamic data type checking

静态类型语言:在编译阶段进行类型检查
动态类型语言:在运行阶段进行类型检查
静态类型检查 > 动态 > 无检查:Needless to say, catching a bug statically is better than catching it dynamically, and catching it dynamically is better than not catching it at all.
静态类型检查可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性 / 健壮性。

静态检查:关于“类型”的检查,不考虑值;
动态检查:关于“值”的检查。
Static Checking
Dynamic Checking

3.1.3 可变性与不变性

3.1.3 Mutability and Immutability

snapshot,防御式拷贝…

 

3.2 设计规约

3.2 Designing Specification

 

3.3 抽象数据类型(ADT)

3.3 Abstract Data Type (ADT)

an abstract data type is defined by its operations

 

3.5 ADT和OOP中的“等价性”

3.5 Equality in ADT and OOP

3.5.1 等价关系

3.5.1 Equivalence Relation

基于抽象函数AF定义ADT的等价操作
等价关系:自反、对称、传递

3.5.2 Immutable类型的等价

3.5.2 Equality of Immutable Types

AF映射到同样的结果,则等价
站在外部观察者角度:对两个对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是等价的。反之亦然。
引用等价性 ==
对象等价性 .equals()
在Object中实现的缺省equals()是在判断引用等价性。
.equals()的对象,其hashCode()的结果必须一致
不相等的对象,也可以映射为同样的hashCode,但性能会变差
x.equals(null) should return false

3.5.3 Mutable类型的等价

3.5.3 Equality of Mutable Types

mutable:观察 / 行为 等价性
观察等价性:在不改变状态的情况下,两个mutable对象是否看起来一致
行为等价性:调用对象的任何方法都展示出一致的结果

x.clone() != xx.clone().getClass() == x.getClass() x.clone().equals(x)从这些contracts中无法确保是deep copy!

 

4.1 可复用性的度量、形态与外部表现

4.1 Metrics, Morphology and External Observations of Reusability

  • Source code reuse 源代码级别的复用
  • Module-level reuse: class/interface 模块级别的复用:类 / 抽象类 / 接口
    • inheritance 继承
    • delegation 委托
  • Library-level reuse: API/Package 库级别的复用:API / 包
  • System-level reuse: Framework 系统级别的复用:框架
    • 白盒框架,通过代码层面的继承进行框架扩展
    • 黑盒框架,通过实现特定接口/delegation进行框架扩展

在这里插入图片描述

 

4.2 面向复用的软件构造技术

4.2 Construction for Reuse

在这里插入图片描述

4.2.1 Behavioral subtyping and Liskov Substitution Principle (LSP)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
泛型中的LSP和通配符…

4.2.2 Delegation and Composition

Delegation(委派/委托):一个对象请求另一个对象的功能
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
API
Framework
在这里插入图片描述

 

4.3 面向复用的设计模式

4.3 Design Patterns for Reuse

在这里插入图片描述

4.3.1 适配器

4.3.1 Adapter

在这里插入图片描述

4.3.2 装饰器模式

4.3.2 Decorator

在这里插入图片描述

4.3.3 外观模式

4.3.3 Facade

wrapper

4.3.4 策略模式

4.3.4 Strategy

在这里插入图片描述
在这里插入图片描述

4.3.5 模版模式

4.3.5 Template

在这里插入图片描述
在这里插入图片描述

4.3.6 迭代器

4.3.6 Iterator

gugugu

 

5.1 可维护性的度量与构造原则

5.1 Metrics and Construction Principles for Maintainability

在这里插入图片描述

5.1.1 常用可维护性指标

5.1.1 Some common-used maintainability metrics

  1. 圈复杂度 Cyclomatic Complexity
  2. 代码行数 Lines of Code
  3. 可维护性指数 Maintainability Index (MI)
  4. 继承的层次数 Depth of Inheritance
  5. 类之间的耦合度 Class Coupling
  6. 单元测试的覆盖度 Unit test coverage

5.1.2 模块化编程

在这里插入图片描述
衡量模块化的5个指标
Five Criteria for Evaluating Modularity

  1. Decomposability (可分解性)
  2. Composability (可组合性)
  3. Understandability (可理解性)
  4. Continuity (可持续性)
  5. Protection (出现异常之后的保护)

模块化编程的5个准则
Five Rules of Modularity Design

  1. Direct Mapping (直接映射)
  2. Few Interfaces (尽可能少的接口)
  3. Small Interfaces (尽可能小的接口)
  4. Explicit Interfaces (显式接口)
  5. Information Hiding (信息隐藏)

5.1.3 Coupling and Cohesion

5.1.4 OO Design Principles: SOLID

  1. 单一责任原则 (SRP) The Single Responsibility Principle
    一个 类/接口 负责一个 特性/功能
  2. 开放-封闭原则 (OCP) The Open-Closed Principle
    对扩展性的开放,对修改的封闭:抽象技术
  3. LSP替换原则 (LSP) The Liskov Substitution Principle Liskov
    派生类必须能够通过其基类的接口使用,客户端无需了解二者之间的差异
  4. 接口隔离原则 (ISP) The Interface Segregation Principle
    不能强迫客户端依赖于它们不需要的接口:只提供必需的接口
  5. 依赖转置原则 (DIP) The Dependency Inversion Principle
    抽象的模块不应依赖于具体的模块,具体应依赖于抽象

OO Design Principles: GRASP
GRASP是关于如何为“类”和“对象”指派“职责”的一系列原则

 

5.2 面向可维护性的设计模式

5.2 Design Patterns for Maintainability

在这里插入图片描述

5.2.1 工厂方法和抽象工厂方法

5.2.1 Factory Method and Abstract Factory Pattern

简单工厂方法(静态工厂方法)
工厂方法
抽象工厂方法
这篇博客都讲到了

5.2.2 代理模式

5.2.2 Proxy

某个对象比较“敏感”/“私密”/“贵重”,不希望被client直接访问到,故设置proxy,在二者之间建立防火墙。
直接访问成本大,利用Proxy。

Observer
Visitor

5.3 面向可维护性的构造技术

5.3 Maintainability-Oriented Construction Techniques

在这里插入图片描述

5.3.1 基于状态的软件构造

5.3.1 State-based construction

基于自动机的编程(Automata-based programming):将程序看作是一个有限状态自动机,侧重于对“状态”及“状态转换”的抽象和编程。

Memento Pattern 备忘录模式(behavioral)

语法驱动的构造
Grammar-based construction

正则表达式
优先级

 


文中的PPT截图来自哈尔滨工业大学软件构造课程课件
本文将在本学期内持续更新完成…

最近有其他更有意义的事去忙所以会咕咕咕一段时间,但这个学期内还是会完成的