需要读的reading MIT6.031 12,13,14
ADT:abstract data type 抽象数据类型
AF:abstraction functions 抽象函数
RI:representation invariants 表示不变量
ADT和RI:如何设计良好的数据结构,通过封装来避免客户端获取数据的内部表示(即表示泄露)
避免潜在的bug--在client和implementer之间建立防火墙
ADT的特性:
Invariant 不变量
representation exposure 表示泄露
abstraction functions(AF) 抽象函数
Mutable and immutable types
3,List是可变的 mutable
并且List是一个接口,需要其他调用这个接口的类(比如ArrayList,LinkedList)去具体实现它内部的方法
如何设计一个AT (抽象类型)?
设计好的ADT,靠“经验法则”,提供一组操作,设计其行为规约spec
1,设计简洁,一致的操作
不要添加只对某种特定的数据类型才有意义的操作。
2,要足以支持client对数据所做的所有操作需要,且用操作满足client需要的难度要低
3,要么抽象,要么具体,不要混合--要么针对抽象设计,要么针对具体应用的设计
Representation independence(表示独立性)
含义:用户使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部的spec和客户端。
除非ADT的操作指明了具体的pre-和post-condition,否则不能改变ADT的内部表示——spec规定了client和implementer之间的契约。
要用到defensive copy
如何测试ADT
测试creators, producers, and mutators:调用observers来观察这些operations的结果是否满足spec;
测试observers:调用creators, producers, and mutators等方法产生或改变对象,来看结果是否正确。
invariant 不变量
一个好的ADT的重要的属性是他有自己的不变量
在任何时候都是true的
并且不变量由ADT负责,与客户端的任何行为无关
为什么需要不变量?
保持程序的正确性,容易发生错误
就像String如果是个可变量,那么在所有使用String的地方,都有可能会出错,需要检查其是否发生了改变。
如何保证对象是不变的呢?
1,将属性访问权限设置为private,在类外只能用方法来获取
2,final关键字也会起到作用
3,(表示泄露)在一个immutable的对象中引用mutable的对象,也会变成mutable的 ,那么如何解决呢?
这要用到defensive copying:复制一个mutable的对象来避免引用造成的表示泄露
copy和clone()
mutable类型通常有复制构造器来让我们创建一个已存在实例的副本实例
或者可以用clone()来复制一个mutable的类型,但这只支持一部分类型
除非迫不得已,否则不要寄希望于客户端上,而是要保证自己的invariants,并避免表示泄露
最好的办法就是使用immutable的类型,彻底避免表示泄露。
来源:oschina
链接:https://my.oschina.net/u/4317906/blog/4033072