第一章回答了如何从不同维度分析软件,以及什么是高质量的软件,第二章回答了软件构造的生命周期与构建模型,第三章主要介绍ADT和OOP
数据类型
java中分为基本数据类型与抽象数据类型,基本数据类型就是平时使用的int,double等,抽象数据类型就是具体的类,如String,二者主要区别是基本数据类型储存在栈中,抽象数据类型储存在堆中,并且基本数据类型是不可变的,只有值,无ID,抽象数据类型有的可变,有的不可变,既有值也有ID,并且java中的自动装箱机制能够帮基本数据类型自动转化为对象数据类型
静态检查和动态检查
Java语言是静态检查类型,好处就是在编译阶段程序就可检测出一些错误,python是动态类型语言,只有在运行阶段才能检查出错误,显然静态类型检查>>动态类型检查>>无检查,静态类型检查主要检查变量的类型是否合法,是否符合规则,动态类型检查主要检查变量的值是否正确
可变数据类型和不可变数据类型
可变数据类型指其内存空间的值可以被改变,不可变数据类型内存空间的值不可被改变,只能改变其引用,当只有一个引用时,二者功能上无差别,但当多个引用指向一个变量时,就可能发生意外,如:
String t = s;
t = t + “c”;
StringBuilder tb = sb;
tb.append(“c”);
快照图:
显然,可变数据类型的缺点就是不安全,但使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收) ;而可变类型最少化拷贝以提高效率 。使用可变数据类型,可获得更好的性能 ;
迭代器
使用迭代器时有一点需要注意,在删除list中的元素时,不要直接调用list的remove方法,因为迭代器中的变量也指向了list,应调用迭代器的remove方法,避免发生意外
规约
为什么要写规约?第一,假设自己记不住,第二,假设别人看不懂代码。规约作用非常大,对程序员来说,可以有效区分责任,对于client来说,节省了很大精力,可以直接阅读spec来使用程序,规约扮演着防火墙的角色。当对于client来说两个方法传入相同值会有相同返回时,这两个方法具有行为等价性。对程序员来说,规约的前置条件如果满足,则后置条件必须满足,如果前置条件不满足,则可以做任何事。如果一个规约的前置条件更弱,后置条件更强的话,这个规约的强度就更高
ADT的操作类型
ADT有四种操作,分别是
Creators(构造器):创建某个类型的新对象,可能实现为构造函数或静态函数(通常称为工厂方法)。
Producers(生产器):从该类型的旧对象创建新对象。
Observers(观察器):获取抽象类型的对象并返回不同类型的对象。
Mutators(变值器):改变对象属性的方法 ,如果返回值为void,则必然意味着它改变了对象的某些内部状态,也可能返回非空类型 。
表示独立性
client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端,我的理解就是对于ADT来说,我们可以改变其内部结构,但是改变内部结构不应该影响其外部的spec,也就是说不应该对客户端造成影响,这就是表示独立性
不变量
ADT内部应该有不变量来保证其正确性,不变量在任何时候都应该是true。
AF和RI
程序内部的数据空间为R,对客户端来说的抽象空间为A,R到A是满射,但不一定单射,也不一定是双射,RI为合法的值空间
表示泄露
在写程序时应该避免表示泄露,否则可能会破坏程序的RI,具体做法是声明private以及其他方法
重写和重载
重写的检查阶段发生在运行阶段,子类重写父类方法,其参数以及返回类型不应该改变,重载在编译阶段检查,要保证其参数类型不同或数量不同