软件构造笔记 3.3 Abstract Data Type (ADT)

抽象数据类型与表示独立性:如何设计良好的抽象数据结构,通过封装来避免客户端获取数据的内部表示(即“表示泄露”),避免潜在bug——在客户端和实现间建立防火墙。

1.抽象数据类型

数据抽象:用一组操作所刻画的数据类型。强调“作用于数据上的操作”,程序员和用户无需关系数据如何具体储存的,只需设计/使用操作即可。ADT是有操作定义的,与其内部如何实现无关。

2.数据和操作的分类

可变类型:提供了可改变其内部数据的值的操作。

不可变类型:其操作不改变内部值,而是构造新的对象。

基于操作可类分为:

构造器(Creators):可能实现为构造函数或静态函数,静态函数一般称为工厂方法。

生产器(Producers):例如String的concat()方法

观察器(Observers):例如size()方法

变值器(Mutators):例如add()方法变值器通常返回void,但是也能返回非空类型。


3.设计好的ADT

设计好的ADT,靠“经验法则”,提供一组操作,设计其行为规约spec,做到以下几点:

1设计简洁、一致的操作。

2要足以支持用户对数据所做的所有操作需要,且用操作满足用户需要的难度要低。

3)要么针对抽象设计,要么针对具体设计,不能混合。

4.表示独立性(Representation Independence

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

5.ADT的测试

测试creators,producers, and mutators:调用observers来观察这些 operations的结果是否满足spec;

测试observers:调用creators,producers, and mutators等方法产生或 改变对象,来看结果是否正确

不变量(Invariants)

不变量在任何时候都是True,有ADT负责,与用户的任何行为无关。不变量便于发现错误,保持程序的“正确性“。

表示泄露不但影响不变形和表示独立性:无法再不影响客户端的情况下改变其内部表示。



防御式拷贝:制作可变对象的副本以避免泄漏对代表的引用。防御性复制是防御性编程的一种方法- 假设客户会试图摧毁不变式 - 事实上可能是真的(恶意黑客),但更可能的是,诚实的错误;确保类不变量保留任何输入,以尽量减少可变性。


可变类型通常具有复制构造函数,它允许您创建一个新的实例来复制现有实例的值。复制可变对象的另一种方法是clone(),它由某些类型支持,但不是全部。


一般来说,应仔细检查所有ADT操作的参数类型和返回类型。如果任何类型都是可变的,请确保实现不返回对其表示的直接引用,否则会产生表示泄露。除非z在迫不得已的情况下,否则不要把责任寄托于客户端,ADT都有责任保证自己的不变性,并避免表示泄露。

保持不变量和避免表示泄露是ADT最重要的一个不变量。

Rep Invariant:某个具体的“表示”是否“合法”;或所有表示值的一个子集,包含了所有合法的表示值;或一个条件,描述什么是“合法”的值。

Abstraction Function:R和A之间映射关系的函数。R为表示空间,A为抽象值构成的空间:客户端看到和使用的值。必为一个满射。


ADT实现者关注表示空间R,用户关注抽象空间A。不同的内部表示需要设计不同的AF和RI,选择某种特定的表示方式R,进而指定某个子集是“合法”的(RI),并为该子集的每个值做出“解释”(AF)——即如何映射到抽象空间中的值


对不可变类型的ADT来说,它在空间的AF是不变的,但其内部表示的R空间中的取值则可以变化。

表示泄露的安全声明(Safety from Rep Exposure):给出理由,证明代码并未对外泄露其内部表示。


ADT中的规约里只能用客户端课件的内容来撰写,包括参数、返回值、异常等。如果规约里要提及“值”,只能用A空间里的指。ADT的规约里也不应该谈及然后内部表示的细节,以及R空间里的任何值。ADT的颞部表示对外部都应严格不可见。故在代码中以注释的形式写出AF和RI,防止被外部看见而破坏独立性和信息隐藏。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值