抽象数据类型ADT

关键词:抽象数据类型与表示独立性

主要内容:前两章研究了数据类型和方法操作的规约,这章将数据与操作复合起来构成ADT,学习如何设计良好的抽象数据结构,通过封装来避免客户端获取数据的内部表示(即“表示泄露”),避免潜在的bug,即在client和implementer之间建立防火墙。

涉及概念:不变量、表示泄露、抽象函数AF、表示不变量RI

ADT

ADT:用户自己定义的数据类型,是由一组操作刻画的,不关心数据的具体表示,只关心数据内涉及到的操作,与底层的具体实现无关

ADT操作类型:(考点:对操作类型的判断

操作名称特点
creator构造器从无到有,其他类型到当前类型
producer生产器从有到新,当前类型到当前类型
observer观察器不产生对象,查看对象的值,从当前类型到其他类型
mutator变值器改变对象的属性

注:可变和不可变数据类型的区别是类中是否有变值器,但是其实不可变数据类型也可以有变值器,只要不改变暴露给用户的属性就可以。(对用户没变,内部解释与映射发生了变化)

构造器可以实现为构造函数(HIT m= new HIT(9,2))或静态函数(工厂方法),变值器通常返回void,但也可能返回boolean判断修改是否成功或返回调用链。

测试ADT

调用observers来观察reators, producers, and mutators的结果是否满足spec;
调用creators, producers, mutators等方法产生或改变对象,来看observer结果是否正确。
风险:如果被依赖的其他方法有错误,可能导致被测试方法的测试结果失效

表示独立与表示泄露

表示独立性RI:只能用类提供的方法改变类的属性值,client使用ADT时无需考虑内部实现方法,ADT内部表示的变化不影响外部speec和client。除非ADT的spec要求,否则操作不能改变ADT内部表示。

不变量:ADT在任何时候都为true(不可变的数据类型的数值不应该发生变化),能保证程序的正确性。方法:private final。

表示泄露:client能都看到甚至修改,影响了不变性和表示独立性。方法:防御性拷贝copy clone

注:类中的方法不要返回对可变类型的直接引用,会造成表示泄露,易错且隐蔽。

注:防御性拷贝可能造成不必要的内存浪费,但寄希望于client也是不好的,最好是只使用immutable类型

有关概念

R空间:实现者看到和使用的值

A空间:客户端看到和使用的值

AF:R空间映射到A空间的抽象函数,满射,未必单射,未必双射

RI:所有合法表示值构成的空间或R->bollean,描述了什么值是合法的

R、A、AF、RI之间没有特别的决定或依赖关系。

设计ADT

设计ADT靠的是经验,要求设计处类和类中所有方法及其规约。

设计原则

(1)每个操作简洁、目的一致

(2)足够client使用,且client使用起来难度低

(3)不将抽象与具体的实现混合

设计步骤

(1)选择R和A

(2)明确合法表示值RI

(3)映射AF,解释合法的表示值

注:所有涉及到的概念RI、AF和表示泄露的安全声明全部写入注释中,但不是A空间的不能写入规约之中;在每个方法return之前都要检查RI是否满足,设计实现checkRep()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值