抽象数据类型(ADT) {ignore=true}
文章目录
1. 抽象类型与用户定义类型
程序员可以自由的定义自己的数据结构,这些数据结构可以是基本类型的扩展,也可以是基本类型的组合。这些数据结构的定义,就是用户定义类型(User Defined Type)。
抽象类型则只强调”作用于数据上的操作“,程序员和client无需关心数据如何存储的,只需设计/使用操作即可。
2. 抽象数据类型
基于以上两个概念的普及,我们可以设计抽象数据类型(Abstract Data Type,ADT)。
3. ADT的操作
通常来说,对于ADT的操作,我们可以分为四种:
- 构造器:构造函数(作为静态方法实现的通常被称为工厂方法)
- 生产器:从已有的对象中生成新的对象
- 观察器:观察对象的某个状态
- 变值器:改变对象的某个状态
4. 设计ADT
应该写spec作为实现的前提。
设计ADT的时候要满足以下几个原则
- 设计简洁、一致的操作
- 要足以支持client对数据所做的所有操作需要,且用操作满足client需要的难度要低
- 要么抽象、要么具体,不要混合 – 要么针对抽象设计,要么针对具体应用的设计。
5. 表示独立性(Representation Independence)
ADT的实现应该与其表示无关,这样才能保证ADT的实现可以被复用。
6. 不变量
不变量保持了程序的正确性。
我们要以最恶意的目光看待client,认为它想破坏ADT的不变量。
将变量设置成private,然后提供public的方法来访问变量,同时public方法中我们可以使用防御式拷贝来保证不变量不被破坏。
7. 表示不变性(Rep Invariant)与抽象函数(Abstraction Function)
ADT开发者关注表示空间R,client关注抽象空间A,我们需要一个函数f来将R映射到A,这个函数就是抽象函数。
如下图所示:
RI则是R中的一个谓词,用来保证R中的元素都是合法的。
选择某种特定的表示方式R,进而指定某个子集是合法的(RI),并为该子集中的每个值做出解释(AF)。
8. 记录AF、RI和Safety from Rep Exposure
- AF: 如何解释每一个R值
- RI: rep中的所有fields何为有效
- Safety from Rep Exposure: 自证清白,代码并未对外泄露其内部表示
看个例子: