软件构造复习——抽象数据类型(PPT6)


一、ADT

在这里插入图片描述
在这里插入图片描述
抽象类型:强调“作用于数据上的操作”,程序员和client无需关心数据如何具体存储的,只需设计/使用操作即可。
在这里插入图片描述
检查类是否满足数据抽象首先要检测类属性是否是private
在这里插入图片描述

操作本身(及其规范)完全定义了数据类型,从数据结构、内存存储或实现的细节中抽象出来。

二、分类类型与操作

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

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

在这里插入图片描述
考:
creator:创建一个全新的对象
producer:产生一个和当前类型一样的对象(从类型的旧对象创建新对象)
observer:获取抽象类型的对象并返回不同类型
mutator:改变对象属性的方法
在这里插入图片描述

常见的creator(构造器、工厂方法、valueof(把其他的对象转成字符串类型))
在这里插入图片描述
在这里插入图片描述
对于mutator常用void,但是也可以返回具体类型或对象。

三、ADT举例

对于各个数据类型的研究举例

int is immutable, so it has no mutators.
creators: the numeric literals 0 , 1 , 2 , …
producers: arithmetic operators + , - , * , /
observers: comparison operators == , != , < , >
mutators: none (it’s immutable)

String is Java’s string type. String is immutable.
creators: String constructors
producers: concat , substring , toUpperCase
observers: length , charAt
mutators: none

List is Java’s list type and is mutable. List is also an interface, which means that other classes provide the actual implementation of the data type, such as ArrayList and LinkedList .
– creators: ArrayList and LinkedList constructors, Collections.singletonList
– producers: Collections.unmodifiableList
– observers: size , get
– mutators: add , remove , addAll , Collections.sort

在这里插入图片描述

四、设计抽象类型

在这里插入图片描述
最好有一些可以以强大方式组合的简单操作,而不是大量复杂的操作。每个操作都应该有明确定义的目的,并且应该有连贯的行为,而不是一堆特殊情况。
例如,我们可能不应该向 List 添加求和运算。 它可能会帮助处理整数列表的客户,但是字符串列表呢? 还是嵌套列表? 所有这些特殊情况都会使 sum 难以理解和使用

五、RI(Representation Independence)表示独立性

在这里插入图片描述

访问这个类,不能直接访问属性(属性要用private。set return 不能跟引用,可跟一个new)
IM类型的属性不可以更改,M类型的属性如果更改的话一定要调用响应的方法修改
在这里插入图片描述
在这里插入图片描述
如下图,不可以直接返回Mutable属性,直接返回的只能是IM的,对于M,我们可以用return new 防止表示泄露
在这里插入图片描述

六、测试抽象数据类型

在这里插入图片描述
测试creators, producers, and mutators:调用observers(要返回当前对象)来观察这些operations的结果是否满足spec;
测试observers:调用creators, producers, and mutators等方法产生或改变对象,来看结果是否正确。
在这里插入图片描述

七、不变量(Invariants)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
private 和 public 关键字指示哪些字段和方法只能在类内访问,哪些可以从类外部访问。
final 关键字还有助于保证在构造对象后不会重新分配此不可变类型的字段
除非迫不得已,否则不要把希望寄托于客户端上,ADT有责任保证自己的invariants,并避免“表示泄露”
最好的办法就是使用immutable的类型,彻底避免表示泄露
在这里插入图片描述
保持不变性和避免表示泄漏,是ADT最重要的一个Invariant

总结:
不要将可变参数合并到对象中; 制作防御副本
返回可变字段的防御副本,返回新实例而不是修改
或返回可变字段的不可修改视图
真正的解决——使用不可变组件,消除防御性复制的需要

八、AF和RI

在这里插入图片描述
开发者关注R空间,用户关注A空间
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
即使是同样的R、同样的RI,也可能有不同的AF,即“解释不同”

按照个人的理解,我认为RI就是对合法子集的描述,AF就是函数F()。
在这里插入图片描述
AF、RI是个程序员看的。
在这里插入图片描述

在这里插入图片描述
代表不变量不仅仅是一个简洁的数学思想。 如果您的实现在运行时断言表示不变量,那么您可以及早捕获错误

checkRep
您当然应该调用 checkRep() 在每个创建或改变表示(creator、producer和mutator)的操作结束时断言表示不变量
在每个方法(包括observer)中调用 checkRep() 意味着您将更有可能捕获由代表暴露引起的代表不变违规

九、有益突变

即你可以变动里面的东西,因为用户不可见,但你要保证Y不可以变
在这里插入图片描述
在这里插入图片描述

十、记录AF/RI

在这里插入图片描述
要把
RI(针对Rep的每一个field以及多个fields之间的关系,进行条件限定,要精确)、
AF(AF:给出client看到的A值是什么,
是对每一个Rep值的“数学运算)、
Safety from rep exporsure (给出理由,证明代码并未对外泄露其内部表示——自证清白)写到注释里
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
final+IM类型可以保证引用和内容都不变
final+M类型只可以保证其引用不变,其内容可以发生改变
在这里插入图片描述
ADT的规约里只能使用client可见的内容来撰写,包括参数、返回值、异常等。
如果规约里需要提及“值”,只能使用A空间中的“值
所有针对属性的注释⽤户不可见,只有针对⽅法的注释用户可⻅
在这里插入图片描述
规约是写在方法之前,描述方法,输入,返回值等信息(给用户去看)
而AF、RI、防止表示泄露都是写在代码里,用注释表示的(给程序员去看)
在这里插入图片描述
在对象的初始状态不变量为true,在对象发生变化时,不变量也要为true
构造器和生产器在创建对象时要确保不变量为true
变值器和观察器在执行时必须保持不变性。
每个方法return之前,用checkRep()检查不变量是否得以保持
在这里插入图片描述

十一、ADT不变量可以替换前提条件

在这里插入图片描述
它对错误更安全,因为所需的条件(排序无重复)可以在一个地方强制执行,即 SortedSet 类型,并且因为 Java 静态检查开始发挥作用,防止根本不满足此条件的值被使用 , 编译时出错。

即把对输入的检查,交给程序里面的checkRep去实现了
在这里插入图片描述

おすすめ

転載: blog.csdn.net/m0_50906780/article/details/118371113