ADT操作的四种类型
ADT的特性:表示泄漏、抽象函数AF、表示不变量RI
基于数学的形式对ADT的这些核心特征进行描述并应用于设计中。
ADT操作的四种类型:
构造器:传入参数为其他类型或只有ADT本身,返回类型为ADT本身
工厂方法
生产器:传入参数为其他类型和ADT本身,返回类型为ADT本身
观察器:传入参数为其他类型,返回类型为ADT本身
变值器:改变对象属性的方法(mutable的ADT),通常返回void,如果返回值为void,则必然意味着它改变了对象的某些内部状态,但变值器也可能返回非空类型
表示独立性Representation Independence
表示独立性:client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端。 除非ADT的操作指明了具体的pre- 和post-condition,否则不能改变ADT的内部表示——spec规定了client和implementer之间的契约。
ADT测试
针对creator:构造对象之后,用observer去观察是否正确
针对observer:用其他三类方法构造对象,然后调用被测observer,判断观察结果是否正确
针对producer:produce新对象之后,用observer判断结果是否正确
表示泄露
representation exposure 表示泄露:不仅影响不变性,也影响了表示独立性:无法在不影响客户端的情况下改变其内部表示
不变量、表示不变量RI
不变量:Invariants
保持不变量:保持程序的“正确性”,容易发现错误在任何时候总是true, 由ADT来负责其不变量,与client端的任何行为无关
表示空间、抽象空间、AF
表示空间R:表示具体值得空间
抽象空间A:client看到和使用的值
在A中无映射值ADT开 发者关注表示空间R,client关注抽象空间A
抽象函数Abstraction Function(AF):R和A之间映射关系的函数,即如何去解释R中的每一个值为A中的每一个值。AF: 满射、非单射、未必双因为R中的部分值并非合法的。
表示不变量Rep Invariant
表示不变性RI:某个具体的“表示”是否是“合法的”
也可将RI看作:所有表示值的一个子集,包含了所有合法的表示值
也可将RI看作:一个条件,描述了什么是“合法”的表示值
不同的内部表示,需要设计不同的AF和RI
选择某种特定的表示方式R,进而指定某个子集是“合法”的(RI),并为该子集中的每个值做出“解释”(AF)——即如何映射到抽象空间中的值。
设计ADT:
- 选择R和A;
- (2) RI --- 合法的表示值;
(3) 如何解释合法的表示值 ---映射AF
做出具体的解释:每个rep value如何映射到abstract value,而且要把这种选择和解释明确写到代码当中
以注释的形式撰写AF、RI
在代码中用注释形式记录AF和RI:(1)要精确的记录RI:rep中的所有fields何为有效,(2)要精确记录AF:如何解释每一个R值,(3)表示泄漏的安全声明
建立不变量:
在对象的初始状态不变量为true,在对象发生变化时,不变量也要为true
构造器和生产器在创建对象时要确保不变量为true
变值器和观察器在执行时必须保持不变性。
在每个方法return之前,用checkRep()检查不变量是否得以保持。