软件构造课程重点
Focus of Software Construction Course
本文按照哈尔滨工业大学软件构造课程的授课顺序展开,
可以帮助读者快速系统地了解高校软件构造课程的授课脉络,
但不适合作为全面系统性学习的主要参考资料。
文章目录
- 软件构造课程重点
- Focus of Software Construction Course
- 1.1 软件构造中的多维视图
- 1.1 Multi-Dimensional Views of Software Construction
- 1.2 软件构造的质量目标
- 1.2 Quality Objectives of Software Construction
- 6.5 软件测试与测试优先的编程
- 6.5 Testing and Test-First Programming
- 2.1 软件生命周期与配置管理
- 2.1 Software Lifecycle and Configuration Management
- 2.2 软件构造的过程、系统和工具
- 2.2 Process, Systems, and Tools of Software Construction
- 3.1 数据类型与类型检验
- 3.1 Data Type and Type Checking
- 3.2 设计规约
- 3.2 Designing Specification
- 3.3 抽象数据类型(ADT)
- 3.3 Abstract Data Type (ADT)
- 3.5 ADT和OOP中的“等价性”
- 3.5 Equality in ADT and OOP
- 4.1 可复用性的度量、形态与外部表现
- 4.1 Metrics, Morphology and External Observations of Reusability
- 4.2 面向复用的软件构造技术
- 4.2 Construction for Reuse
- 4.3 面向复用的设计模式
- 4.3 Design Patterns for Reuse
- 5.1 可维护性的度量与构造原则
- 5.1 Metrics and Construction Principles for Maintainability
- 5.2 面向可维护性的设计模式
- 5.2 Design Patterns for Maintainability
- 5.3 面向可维护性的构造技术
- 5.3 Maintainability-Oriented Construction Techniques
1.1 软件构造中的多维视图
1.1 Multi-Dimensional Views of Software Construction


1.2 软件构造的质量目标
1.2 Quality Objectives of Software Construction
- 外部质量因素影响用户
External quality factors affect users - 内部质量因素影响软件本身和它的开发者
Internal quality factors affect the software itself and its developers - 外部质量取决于内部质量
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
- 虽然需要折中,但“正确性”绝不能与其他质量因素折中
- 最重要的几个质量因素
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

- 瀑布过程:线性推进,阶段划分清楚,整体推进,无迭代,管理简单,无法适应需求增加/变化;
- 增量过程:线性推进,增量式(多个瀑布的串行),无迭代,比较容易适应需求的增加;
- V字模型:for verification and validation
- 原型(迭代):在原型上持续不断的迭代发现用户变化的需求。
迭代:开发出来之后由用户试用/评审,发现问题反馈给开发者,开发者修改原有的实现,继续交给用户评审。
循环往复这个过程,直到用户满意为止。时间代价高,但开发质量也高。 - 螺旋(迭代):非常复杂的过程,多轮迭代基本遵循瀑布模式。
每轮迭代有明确的目标,遵循“原型”过程,进行严格的风险分析,方可进入下一轮迭代
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):存储软件的各配置项随时间发生变化的信息 + 基线。
版本:为软件的任一特定时刻(Moment)的形态指派一个唯一的编号,作为“身份标识”。
本地 / 集中 / 分布式 版本控制系统
2.1.4 软件配置管理工具:以Git为例
2.1.4 Git as an example of SCM tool







2.2 软件构造的过程、系统和工具
2.2 Process, Systems, and Tools of Software Construction

2.2.1 软件构造的一般过程
2.2.1 General process of software construction

- Programming


- Review and static code analysis
- 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.
- Debugging and Testing
- 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
借助于工具,将软件构造各阶段的活动“自动化”(编译、打包、静态分析、测试、生成文档、部署…)尽可能脱离“手工作业”,提高构造效率

3.1 数据类型与类型检验
3.1 Data Type and Type Checking
3.1.1 数据类型
3.1.1 Data type in programming languages

重载:同样的操作名可用于不同的数据类型
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.
静态类型检查可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性 / 健壮性。
静态检查:关于“类型”的检查,不考虑值;
动态检查:关于“值”的检查。

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
- 圈复杂度 Cyclomatic Complexity
- 代码行数 Lines of Code
- 可维护性指数 Maintainability Index (MI)
- 继承的层次数 Depth of Inheritance
- 类之间的耦合度 Class Coupling
- 单元测试的覆盖度 Unit test coverage
5.1.2 模块化编程

衡量模块化的5个指标
Five Criteria for Evaluating Modularity
- Decomposability (可分解性)
- Composability (可组合性)
- Understandability (可理解性)
- Continuity (可持续性)
- Protection (出现异常之后的保护)
模块化编程的5个准则
Five Rules of Modularity Design
- Direct Mapping (直接映射)
- Few Interfaces (尽可能少的接口)
- Small Interfaces (尽可能小的接口)
- Explicit Interfaces (显式接口)
- Information Hiding (信息隐藏)
5.1.3 Coupling and Cohesion
5.1.4 OO Design Principles: SOLID
- 单一责任原则 (SRP) The Single Responsibility Principle
一个 类/接口 负责一个 特性/功能 - 开放-封闭原则 (OCP) The Open-Closed Principle
对扩展性的开放,对修改的封闭:抽象技术 - LSP替换原则 (LSP) The Liskov Substitution Principle Liskov
派生类必须能够通过其基类的接口使用,客户端无需了解二者之间的差异 - 接口隔离原则 (ISP) The Interface Segregation Principle
不能强迫客户端依赖于它们不需要的接口:只提供必需的接口 - 依赖转置原则 (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截图来自哈尔滨工业大学软件构造课程课件
本文将在本学期内持续更新完成…
最近有其他更有意义的事去忙所以会咕咕咕一段时间,但这个学期内还是会完成的
