软件构造实验二要求实现ADT,于是我去MIT的网站上学习了ADT相关知识,将关键的部分翻译成中文搬运到这里。
Reading 10: Abstract Data Types
抽象意味着什么
抽象数据类型是软件工程的通用准则,并以许多名字用在不同的领域,这里是抽象思想中的一些名词:
- 抽象。用更简单、更高级的思想省略或隐藏低级的实现。
- 模块化。将一个系统划分为成分或模块,其中每一部分都可以被系统中其他部分实现,测试,推理和重用。
- 封装。在模块周围建立保护,使模块只对其内部的行为负责,其它部分的bug不会影响到该部分的整体性。
- 信息隐藏。对系统中其他部分隐藏该模块的实现细节,使该模块中的信息可以在其他部分修改之后再进行修改。
- 关注点分离。使每个模块有自己特定的责任,而不是被其他模块分享。
划分类型与操作
不管是原生类型还是用户定义的类型,都可以被划分为可修改的和不可修改的。可修改的类型可以被修改:那意味着,他们提供一些方法,执行这些方法时,会导致该对象中其他的方法运行后得到不同的结果。例如,StringBuilder是可修改的,String是不可修改的。
抽象数据类型的操作可以被定义成如下几种:
- 创建者(creators) 创建该类型的新对象。一个创建者可以以一个对象为参数,但不会构造该对象的类型。
- 生产者(producers) 从该类型的旧对象中创建新对象。例如String类型的concat方法,接受两个string并且产生他们的级联。
- 观察者(observers) 接受一种类型的抽象数据然后返回另一种类型的对象。例如List类型的size方法,返回int类型数据。
- 修改者(mutators) 修改对象。例如List类型的add方法,通过在尾部添加元素修改List。
抽象数据类型举例
int 是JAVA的原生整数类型,int是不可修改的,所以它没有修改者。
- 创建者:字面整数如0,1,2…
- 生产者:算数运算符如+,-,*,/
- 观察者:比较运算符如==,!=,<,>
- 修改者:不存在
List是JAVA的列表类型,是可修改的,List也是一个接口,意味着其他类提供了该类型的实现,包括ArrayList和LinkedList。
- 创建者:ArrayList和LinkedList构造器,Collections.singletonList方法。
- 生产者:Collections.unmodifiableList方法
- 观察者:size,get方法
- 修改者:add,remove,addAll,Collections.sort方法
String是JAVA的字符串类型。String是不可修改的
- 创建者:String构造器,静态valueOf方法
- 生产者:concat,substring,toUpperCase方法
- 观察者:length,charAt方法
- 修改者:不存在
设计抽象类型
设计抽象类型包括选择好的操作然后决定它们应该做什么。这里是一些好的建议。
最好实现少的、简单的、可以被很好地组合重用的方法,而不是很多复杂的方法
每个方法都应该有一个定义好的目的,并且应该有一系列连贯的动作而不是复杂的特殊动作。例如我们不应该为List类型增加sum方法,虽然它可能为客户端提供对整数的操作,但对于String和嵌套List却无能为力,这会让sum变成一个难以理解难以使用的方法。
提供的操作应该是充足的,以保证客户端可以使用它做可能的各种运算。一个好的验证是:检查是否该类型的所有特性都能被提取。例如,如果没有get方法,我们将不能确定List中的元素是什么,基础的信息不应该很难被提取。例如,size方法对于List类型不是必须的,因为我们可以通过get方法确定List的大小,但这是不充分和不方便的。
类型可以是泛型的:例如列表、集合、或图。或者针对特定类型:街道的映射、员工的数据库、通讯录等等。但是它不应该混淆泛型与特定类型