3.3抽象数据类型

  1. ADT的操作的四种类型
  2. 表示独立性
  3. 表示泄露
  4. 不变量与表示不变量
  5. 表示空间,抽象空间,AF
---------------------------------------------------------------------------------------------------------------------------------

1.ADT的四种操作

ADT是更强调作用于数据上的操作,不管其怎样实现

操作类型

  • creator 构造器,用一些东西创建出一个新的对象(用木头造纸)other type->new object
  • producer 生产器 用旧的对象产生新的对象(旧纸造新纸)old object->new object
  • Observer 观察器 观察一个对象 的特征,返回特征值(观察纸,返回值的厚度)(类型变了)object->other type
  •  Mutator 变值器 改变对象某个属性(改变纸的厚度)

构造器:构造函数或者静态函数(工厂方法)

第三章:ADT与OOP (第三节)

---------------------------------------------------------------------------------------------------------------------------------

2.表示独立性(rep independence)

表示独立性: client使用ADT时无需考虑其内部如何实现, ADT内部表示的变化不应影响外部spec和客户端
除非ADT的操作指明了具体的pre-post-condition,否则不能改变ADT的内部表示——spec规定了clientimplementer之间的契约

---------------------------------------------------------------------------------------------------------------------------------

3.表示泄露

可以从外部直接访问某个变量(设为public时)

第三章:ADT与OOP (第三节)

不仅影响不变性,也影响了表示独立性:无法在不影响客户端的情况下改变其内部表示

防止表示泄露:--private final

第三章:ADT与OOP (第三节)

但是由于Date是mutable的对象

                如果在一个方法里使用getTimestamp方法:

                第三章:ADT与OOP (第三节)

对象的表示不变量Date仍然被改变了

    

                第三章:ADT与OOP (第三节)

所以我们又需要用到防御式拷贝


第三章:ADT与OOP (第三节)

但是这样依然有问题  , 在创建Tweet对象之前,为对象属性赋值的date若有引用,仍然可以改变引用指向的对象的值,进而影响内部表示:

                    第三章:ADT与OOP (第三节)                              

这里24个tweet的date属性,引用的是同一个对象,因此会有:

                                   第三章:ADT与OOP (第三节)    

                        仍然使用防御性拷贝第三章:ADT与OOP (第三节)

                        第三章:ADT与OOP (第三节)


防御式拷贝就是模仿immutable的,所以说,归根到底就是mutable对象的问题

---------------------------------------------------------------------------------------------------------------------------------

4.不变量

不变量:在任何时候总是trueADT来负责其不变量,与client端的任何行为无关

    其在整个生命周期中,总是表现出相同的价值。

(在我看来就是类的成员变量,最好定义为private final,使用imutable的对象 以防止表示泄露)


保持不变性和避免表示泄漏,是ADT最重要的一个Invariant


---------------------------------------------------------------------------------------------------------------------------------

5.表示不变量与抽象函数


(1)Rep Space表示空间:表示值所处的空间

          一般情况下ADT的表示比较简单,有些时候需要复杂表示,

(2)  Abs Space 抽象空间:client看到和使用的值

          ADT实现者关注R,而用户关注A

 (3)抽象函数AF:将表示空间的值映射到抽象空间        不一定是单射,但一定是满射

 (4)表示不变量RI: 在表示的过程中,就出现了表示不变性RI:

            即某个具体的“表示”是否是“合法的”

            也可将RI看作:所有表示值的一个子集,包含了所有合法的表示值 

            也可将RI看作:一个条件,描述了什么是“合法”的表示值

第三章:ADT与OOP (第三节)

  • 不同的内部表示,需要设计不同的AFRI

(图一)同样的R 不同的RI 同样的AF

第三章:ADT与OOP (第三节)

实验时要随时检查RI是否满足:checkRep()--一般是在每个函数返回前检查

在对象的初始状态不变量为true,在对象发生变化时,不变量也要为true

  • 构造器和生产器在创建对象时要确保不变量为true 
  • 变值器和观察器在执行时必须保持不变性。
    第三章:ADT与OOP (第三节)


Rep中不可出现null

---------------------------------------------------------------------------------------------------------------------------------

5.以注释的形式撰写AF和RI

每个类的内部都需要又AF和RI,还要有表示泄露的安全声明

第三章:ADT与OOP (第三节)

可以用不变量的方式取代precondition










      





相关文章: