抽象数据类型(ADT)
ADT的特性:表示泄漏、抽象函数AF、表示不变量
将ADT的操作分类
你可以从下图来理解
T是ADT本身,t;是其他类型,*和+说的都是出现次数,和正则是一样的
creator 构造器
直接构造出一个新的对象,可以有参数,但是不能直接将参数作为返回值
可能实现为构造函数或者静态函数
producer 生产器
基于旧的对象生成新的对象
observer 观察器
查看rep的值或者状态
mutator 变值器,改变对象属性的方法
对ADT进行修改
如果返回值是void,则必然意味着它改变了对象的某些内部状态
变值器也可能返回非空类型
Abstract Data Type Example
int
int is immutable, so it has no mutators
creators:the numeric literals 0,1,2,……
producers:arithmetic operators +,-,*,/
observers:comparison operators ==,!=,<,>
mutators:none
string
creators: string constructors
producers: concat,substring,toUpperCase
observers: length, charAt
mutators: none
List
creators: ArrayList and LinkedList constructors, Collections.singletonList
producers: Collections.unmodifiableList
observers: size , get
mutators: add , remove , addAll , Collections.sort
others
Integer.valueOf() creator
BigInteger.mod() Producer
List.addAll() Mutator
String.toUpperCase() Producer
Set.contains() Observer
Map.keySet() Observer
Collections.unmodifiableList() Producer
BufferedReader.radLine() Mutator
设计一个抽象类型(设计原则)
提供一组操作,设计其行为规约spec
设计简洁、一致的操作
要足以支持client对数据所作的所有操作需要,且用操作满足client需要的难度要低
要么针对抽象设计,要么针对具体应用设计
representation independence(表示独立性)
lient使用ADT是无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端
比如List的两种实现
别让用户用了你的field
Testing an Abstract Data Type
测试creators,producers,and mutators;调用observers来观察这些operations的结果是否慢则sepc
测试observers:调用creators,producers,and mutators等方法产生或者改变对象,来看结果是否正确
invariants
这是一个抽象的概念,也就是说你的adt中总有一些东西要满足一些约束条件以保证程序的正确性,不变量在任何时候总是true,这是由ADT负责的,与client的任何行为没有关系
对于immutable类型的数据,总是保持不变性的,否则的话,任何使用string的时候,都要检查是否改变
rep invariant and abstraction function
两个空间
R:the space of repsentation values,开发者关注
A:the space of abstract values抽象值构成的空间,client看到和使用的值
举个例子:
我们现在要使用一个string代表一个字符的集合
那么RA就应该像这样
AF抽象函数
R和A之间映射关系的函数
AF:R -> A
在写AF的时候,将field映射成需要呈现给客户端的东西就行了
RI表示不变性
RI:R -> boolean
RI表示不变性:某个具体的“表示”是否是“合法的”
然后在写RI的时候就只要将合法的子集写上就可以了
AF和RI
给个例子:
不同的内部表示,需要设计不同的AF和RI
选择某种特定的表示方式R,进而制定某个自己是“合法”的(RI),并为该自己中的每个值做出“解释”(AF)–即如何映射到抽象空间中的值
在所有有可能改变热捧的方法内部都要检查
RI中没有null,这是程序员之间的潜规则
beneficent mutation
对immutable的ADT来说,它在A空间的abstract value应是不变的,但其内部表示的R空间中的取值则可以是变化的
举个例子,现在除数和被除数是两个field,但是他们有公约数,然后就可以化简,这个时候你改变的field,但是,化简是有益的
Documenting the AF, RI, and Safety from Rep Exposure
在代码中用注释形式记录AF和RI
表示泄漏的安全声明
举个例子
证明没有rep exposure的常用套路
field是private的
使用的数据是immutable类型的
在creator、producer、observer、mutator(如果有返回值)方法中使用了防御式编程
ADT invariants replace preconditions
用ADT不变量取代复杂的前置条件,相当于将复杂的前置条件封装到了ADT内部
欢迎关注公众号BBIT
让我们共同学习共同进步!