课件中有关ADT的讲解(摘录自学长的翻译中的部分内容)

抽象:规格说明使得使⽤者只需要弄懂规格说明并遵守前置条件,⽽不是让他们去弄懂底层的代码实现
模块化:单元测试和规格说明都帮助了将⽅法模块化
封装:⽅法中的局部变量都是被封装的,因为他们仅仅可以在⽅法内部使⽤。与此相对的是全局变量和指向 可变对象的别名,它们会对封装带来很⼤损害。
信息隐藏:规格说明就是⼀种信息隐藏,它使得实现者可以⾃由的更改实现代码。
功能分离:⼀个规格说明应该是逻辑明确的,即它不能有很多特性,⽽应该完成好⼀个功能。

创建者creator:创建⼀个该类型的新对象。⼀个创建者可能会接受⼀个对象作为参数,但是这个对象的类型 不能是它创建对象对应的类型。
⽣产者producer:通过接受同类型的对象创建新的对象。例如, String 类⾥⾯的 concat ⽅法就是⼀个 ⽣产者,它接受两个字符串然后据此产⽣⼀个新的字符串。
观察者observer:接受⼀个同类型的对象然后返回⼀个不同类型的对象/值。例如 List 的 size ⽅法,它 返回⼀个 int 。
改造者mutator:改变对象的内容,例如 List 的 add ⽅法,它会在列表中添加⼀个元素。
表⽰独⽴
特别地,⼀个好的抽象数据类型应该是表⽰独⽴的。这意味着它的使⽤和它的内部表⽰(实际的数据结构和实现) ⽆关,所以内部表⽰的改变将对外部的代码没有影响。例如, List 就是表⽰独⽴的——它的使⽤与它是⽤数组还 是连接链表实现⽆关。 如果⼀个操作完全在规格说明中定义了前置条件和后置条件,使⽤者就知道他应该依赖什么,⽽你也可以安全的对 内部实现进⾏更改(遵循规格说明)。
不变量
回想我们之前讨论过的关于ADT的内容,什么设计会产⽣好的ADT?其中最重要的⼀点就是它会保护/保留⾃⼰的不 变量。 不变量是⼀种属性,它在程序运⾏的时候总是⼀种状态,⽽不变性就是其中的⼀种:⼀旦⼀个不变类型的对 象被创建,它总是代表⼀个不变的值。当⼀个ADT能够确保它内部的不变量恒定不变(不受使⽤者/外部影响),我 们就说这个ADT保护/保留⾃⼰的不变量. 当⼀个ADT保护/保留⾃⼰的不变量时,对代码的分析会变得更简单。例如,你能够依赖字符串不变性的特点,在分 析的时候跳过那些关于字符串的代码;或者当你尝试基于字符串建⽴其他的不变量的时候,也会变得更简单。与此 相对,对于可变的对象,你将不得不对每⼀处使⽤它的代码处进⾏审查。

可变类型的不可变包装
Java的collections类提供了⼀种有趣的“折中”:不可变包装。 Collections.unmodifiableList() 会接收⼀个(可变) List 然后将其包装为⼀个不可变对象——它的 set() , add() , remove() ,等操作都会抛出异常。所以你可以将⼀个 List 包装为不可变对象(记得将以前对 于 List 的索引丢掉),然后将它传⼊其他地⽅使⽤。 这种⽅法的缺点就是你只能在运⾏时获得不可变性,⽽不是编译时。Java不会在编译的时候对你对“不可变”列表的 修改提出警告。但是这总⽐什么都不做好,所以使⽤不可变的列表、映射、和集合也是减少bug的好⽅法。

表⽰域(space of representation values)⾥⾯包含的是值具体的实现实体。在简单的情况下,⼀个抽象类型只需 要实现为单个的对象,但是更常⻅的情况是使⽤⼀个很多对象的⽹络。
抽象域⾥⾯包含的则是类型设计时⽀持使⽤的值。这些值是由表⽰域“抽象/想象”出来的,也是使⽤者关注的。例 如,⼀个⽆限整数对象的抽象域是整个整数域,但是它的实现域可能是⼀个由原始整数类型(有限)组成的数组实 现的,⽽使⽤者只关注抽象域。

抽象函数abstraction function是表⽰值到其对应的抽象值的映射:
AF : R → A
这种映射是满射,但不⼀定是单射(不⼀定是双射)。
表⽰不变量rep invariant是表⽰值到布尔值的映射
RI : R → boolean
对于表⽰值r,当且仅当r被AF映射到了A,RI®为真。换句话说,RI告诉了我们哪些表⽰值是“良好组织”的(能够去 表⽰A中的抽象值)。

⼀个ADT的实现不仅是选择表⽰域(规格说明)和抽象域(具体实现),同时也要决定哪⼀些表⽰值是合法 的(表⽰不变量),合法表⽰会被怎么解释/映射(抽象函数)

对于RI(表⽰不变量),仅仅宽泛的说什么区域是合法的并不够,你还应该说明是什么使得它合法/不合法。 对于AF(抽象函数)来说,仅仅宽泛的说抽象域表⽰了什么并不够。抽象函数的作⽤是规定合法的表⽰值会 如何被解释到抽象域。作为⼀个函数,我们应该清晰的知道从⼀个输⼊到⼀个输⼊是怎么对应的。

规格说明不应该谈论具体的表⽰/实现细节,例如表⽰域⾥⾯的值。它应该认为表⽰本⾝(私有区域)对于使⽤者 是不可⻅的,就像是⽅法⾥⾯的局部变量对外部不可⻅。这也是为什么我们在注解表⽰不变量和抽象函数的时候使 ⽤的是"\"注释⽽⾮典型的Javadoc格式。如果我们使⽤Javadoc注释的话,内部的实现细节会出现在规格说明中, ⽽这会影响表⽰独⽴性以及信息隐藏。

     如果⼀个抽象数据类型的不变量满⾜: 
  1. 被创建者或⽣产者创建;
  2. 被改造者和观察者保持;
  3. 没有表⽰暴露。
    那么这种类型的所有实例的不变量都是成⽴的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值