抽象数据类型概念
与传统类型关注数据的具体表示相反,抽象类型强调“作用于数据上的操作”,用户无需关心数据是如何具体存储的,只需使用操作即可。
就是说,ADT是由操作定义的,与其内部如何实现无关。ADT的操作可以分为以下几类:
- 构造器:从无到有,创建一个新的对象,可能实现为构造函数或静态函数。
- 生产器:从有到有(更多),从一个或多个对象出发, 生成一个新的对象。
- 观察器:从有到无,并不改变任何ADT的属性。
- 变值器:改变对象属性的方法,immutable类型没有该类的方法。
设计ADT
要求
根据需求,提供一组操作,并设计其行为规约spec。
-
设计简洁(功能简单)、一致(可以处理不同情况,例如不同数据类型)的操作。
-
操作全面,但若是所花代价太大,可以不设计。
-
Representation Independence 表示独立性:ADT内部表示的变化不应影响外部spec,并且用户无法改变ADT的内部表示,除非ADT的操作指明了具体的pre- and post-condition。
- 不能暴露类的属性,均为private。不能假设用户知道该类的属性,要设计操作来获得用户可能需要的信息,但不一定是属性。
- 避免表示暴露,即直接返回类的某个属性,可以使用defensive copy来避免。
-
Invariant 不变量:保持不变性(尽量保证对象内部的属性为immutable类型)(private final immutable)和避免表示泄露(若为immutable类型,则不需要defensive copy),是ADT最重要的一个Invariant。
-
Rep Invariant 表示不变量:另一个重要的ADT invariants,RI可以看作是所有表示值(R空间)的一个子集,包含了所有合法的表示。
并且要随时检查RI是否满足,需要编写checkRep()方法,并在所有可能改变rep的方法内都要检查(observer可以不用,但最好也要检查)。 -
Abstraction function(AF)抽象方程:是R到A的映射,即如何去解释R中的每一个值为A中的每一个值,是满射,但不一定是单射,也不一定是双射。 在ADT设计中应该在属性field之后声明RI和AF。
-
表示泄露的安全声明:
-
ADT的规约spec:只能使用客户可见的内容来撰写,包括参数、返回值、异常等。不能谈及R空间的值,只能用A空间的值。