软件构造1-3章

章节 内容
1 什么是“高质量的软件”、如何从不同维度刻画软件
2 软件构造的基本过程和步骤
3 软件构造的理论基础——ADT技术基础——OOP

1.1软件构造的多维度视图

1.1.1从三个维度看软件系统的构成

– By phases: build- and run-time views 按阶段划分:构造时/运行时视图
– By dynamics: moment and period views 按动态性划分:时刻/阶段视图
moment:特定时刻的软件形态
Period view: 软件形态随时间的变化
– By levels: code and component views 按构造对象的层次划分:代码/构件视图
code:代码的逻辑组织 functions, classes, methods, interfaces
component:代码的物理组织 files, directories, packages, libraries
在这里插入图片描述
编译型语言Java
在这里插入图片描述
解释型语言Perl,Python
在这里插入图片描述

1.1.2将“软件构造”看作“不同视图之间的转换”

在这里插入图片描述

1.2质量指标

1.2.1Quality properties of software systems

– External vs. internal quality factors

外部质量因素影响用户
内部质量因素影响软件本身和它的开发者
外部质量取决于内部质量

– Important external quality factors

1.正确性:按照预先定义的“规约”执行
方法:
1.测试和调试:发现不正确、消除不正确
2.防御式编程:在写程序的时候就确保正确性

2.健壮性:针对异常情况的处理
异常处理:所谓的“异常”,取决于spec的范畴
3.可扩展性:对软件的规约进行修改,是否足够容易?应对变化

– Tradeoff between quality factors

1.2.2Five key quality objectives of software construction

– Easy to understand: elegant and beautiful code / understandability
– Ready for change: maintainability and adaptability
– Cheap for develop: design for/with reuse: reusability
– Safe from bugs: robustness
– Efficient to run: performance

3

章节 内容
3-1 “数据类型”及其特性
3-2 方法和操作的“规约”及其特性
3-3 将数据和操作复合起来,构成ADT

3.1数据类型及检查

3.2设计规约

更强的后置
条件意味着实现的自由度更低了在图中的面积更小
更弱的前置
实现时要处理更多的可能输入,实现的自由度低了,面积更小

3.3抽象数据类型(ADT)

抽象数据类型与表示独立性:如何设计良好的抽象数据结构,通过封
装来避免客户端获取数据的内部表示(即“表示泄露”),在client和implementer之间建立“防火墙”
抽象类型:强调“作用于数据上的操作”,程序员和
client无需关心数据如何具体存储的,只需设计/使用操作即可。
在这里插入图片描述
表示独立性:client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端。
不变量:在任何时候总是true,由ADT来负责其不变量,与client端的任何行为无关
保持程序的“正确性”,容易发现错误
假设client有“恶意”破坏ADT的不变量—defensive programming
保持不变性和避免表示泄漏,是ADT最重要的一个Invariant!
表示不变量和抽象函数
在这里插入图片描述
rep的值和客户端看到的值
表示不变性RI:某个具体的“表示”是否是“合法的”
在对象的初始状态不变量为true,在对象发生变化时,不变量也要为true
构造器和生产器在创建对象时要确保不变量为true
变值器和观察器在执行时必须保持不变性。
在每个方法return之前,用checkRep()检查不变量是否得以保持。
抽象函数:R和A之间映射关系的函数,即如何去解释R中的每一个值为A中的每一个值。
一般函数不允许一对多,多对一是允许的
单射:一对一,A中有剩余
满射:所有 “B” 的元素都有至少一个相对的 “A” 的元素
双射:完美一对一
在这里插入图片描述
选择某种特定的表示方式R,进而指定某个子集是“合法”的(RI),并为该子集中的每个值做出“解释”(AF)——即如何映射到抽象空间中的值。
checkRep:在所有可能改变rep的方法内都要检查
Observer方法可以不用,但建议也要检查,以防止你的“万一”
beneficent mutation (有益的可变性)
对immutable的ADT来说,它在A空间的abstract value应是不变的。
但其内部表示的R空间中的取值则可以是变化的。
举例:toString输出分数时,进行了约分。
这种mutation只是改变了R值,并未改变A值,对client来说是
immutable的“AF并非单射”,从一个R值变成了另一个R值
作用:通过牺牲immutability的部分原则来换取“效率”和“性能”
– Caching:例如通过cache暂存某些频繁计算的结果
– Data structure rebalancing:例如对tree数据结构进行插入或删除节点之后
– Lazy computation:上例中在toString()的时候才进行约分计算
在这里插入图片描述
在这里插入图片描述

3.4面向对象的编程

接口提供API,有不同的子类实现
在这里插入图片描述
接口:确定ADT规约
类:实现ADT
在这里插入图片描述
问题:接口定义中没有包含constructor,也无法保证所有实现类中都包含了同样名字的constructor。故而,客户端需要知道该接口的某个具体实现类的名字
解决:静态工厂
在这里插入图片描述
继承和重写:
严格继承:子类只能添加新方法,无法重写超类中的方法,加final关键字无法重写
父类方法可以复用,在父类中写,特殊子类重写
没有可复用的方法,直接留空,每个子类都重写
override关键字和super
在这里插入图片描述
扩展父类方法
在这里插入图片描述
使用this或者that构造,必须是第一个构造。
在这里插入图片描述
抽象类和抽象方法:
子类共有的在父类中实现,子类特有的定义为抽象方法,分别在子类中实现。
多态 Polymorphism

  1. 特殊多态:函数的功能重载
    多个函数有相同的名字,但有不同的参数列表和返回值类型
    overload在编译时根据引用类型决定
    在这里插入图片描述
    override在运行时根据对象类型决定
    在这里插入图片描述
    • MUST
      不同的参数列表 参数数量或者参数类型
    • CAN
      相同/不同的返回值类型
      相同/不同的public/private/protected
      相同/不同的异常
      可以在同一个类内重载,也可在子类中重载
  2. 参数多态和泛型编程
    类型变量是非限定标识符,我们有泛型类、泛型接口、泛型方法
    这里有一些展示
    子类型 subtyping
    重载 overloading

猜你喜欢

转载自blog.csdn.net/a1058420631/article/details/91446293
1-3