软件构造课程思考8

发布时间 2023-05-25 22:00:02作者: Zzzzzzxz

6 抽象数据类型 ADT
6.1 抽象和用户定义类型
编程语言具有内置类型(如整数、布尔值、字符串等)和内置过程(如输入和输出)。

用户可以定义自己的数据类型和过程——用户定义的类型。

数据抽象:由一组操作刻画的数据类型,强调“作用于数据上的操作”,程序员和客户端无需关心数据的具体存储方式,只需要设计/使用操作即可。

抽象数据类型T的操作和规约刻画了T 的特征

6.2 分类类型和操作
6.2.1 可变和不可变数据类型
可变数据类型的对象:提供了可改变其内部值的操作

不可变数据类型的对象:操作不可改变其内部值

通常,编程语言对于一些类型会提供两种方式,如string和stringbuilder

6.2.2 四种操作
构造器:(从无到有)创建该类型的新对象

生产器:(从有到新)从该类型的旧对象创建新对象,如String的concat()方法

观察器:获取抽象类型的对象并返回不同类型的对象,如.size()

变值器:改变对象属性的方法,如.add()

6.2.3 方法签名
构造器:构造函数或者静态函数(实现为静态方法的构造器通常称为工厂方法,如String.valueOf(Object Obj) (返回参数的字符串形式))

变值器:返回值如果为void,则必然意味着它改变了对象的某些内部状态。不过也有可能返回非空类型,如Set.add()返回一个boolean来明确说明是否成功;Component.add()返回对象本身。

6.4 设计抽象数据类型
良好的ADT设计:靠“经验法则”,提供一组操作,设计其行为规约spec

spec中应有的内容:参数、返回值、异常等

spec中不应谈及任何内部表示的细节,以及R空间中的任何值

因此,AF和RI应该写在注释里,而不能写在javadoc中,否则表示泄漏

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

2.提供功能要足够强,足以满足用户需求。

判断是否满足用户需求的方法:看对象的每个需要被访问到的属性是否能被访问到

3.要么针对抽象操作,要么针对具体应用的设计:

类型可以是泛型的:例如,列表、集合或图形;或者它可能是特定领域的:街道地图、员工数据库、电话簿等。

但是不可以是混合以上两种情况的。面向具体应用的类型不应该包含通用方法,面向通用的类型不应该包含面向具体应用的方法。

6.5 表示独立性
表示独立性:client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端

eg: list提供的操作与其实现为linked list还是array list无关

通过前提条件和后置条件充分刻画了ADT的操作,spec规定了client和implementer之间的契约,明确了client知道可以依赖哪些内容,implementer知道可以安全更改的内容。