如何理解数据抽象?
对于程序员和client来说,一个/组数据如何存储、表示、实现并不重要,重要的是它表示什么?它能执行哪些操作?
因此拿到一个抽象数据,我只需要直到它的抽象表示(图/数组/集合etc.)、表示含义、相关操作即可拿来使用。
抽象数据的类型和操作
类型:可变/不可变,
操作
Creators:其中以静态方法实现的构造器称为工厂方法
Producers
Mutators:通常返回void,也可能返回非空类型
Observers
对于不可变类型的抽象数据来说,不存在Creators
ADT设计经验
良好的Spec
操作简洁、一致、复用性高
复杂的操作最好由一系列简单操作复用实现
方法覆盖所有class所有属性,且代价不能太高
要么抽象,要么具体
抽象的描述共性
具体的不要太过考虑复用性
表示独立性
通过spec的precondition和postcondition严格控制
client得知道能获得什么属性,能使用什么方法
implementer无论在里面怎么乱造,只要确保自己的承诺即可
如何测试一个ADT?
测试Creator、producer、mutator的时候,调用observers
测试observer的时候,使用剩下三个改变对象,看看对不对
ADT的责任
keep invariant
avoid rep exposure
使用不可变类型
拷贝式防御
RI与AF
为什么要有这么个东西?
ADT用来表示某个对象,但如何表示需要Implementer自行决定和实现,RI与AF提供了一个凡事,其含义如下
RI:定义哪些是合法值
在使用的值field中,解释哪些是有效
AF:如何根据ADT的rep映射到它向client展示的东西
精确记录AF,如何解释每一个R值
Safety from rep exposure
解释如何保证避免rep exposure
Rep check()随时进行检测,保证在实现的任何时候,RI得到保证。
一点感想:
ADT的内容其实就相当于设计一个产品,他主要涉及两个主体:客户&设计者
对客户:
spec相当于说明书,告诉别人我的产品是什么,想用来干什么,怎么用,客户知道了这些就可以了,然后拿着产品去随意乱造。
creator、producer、mutator、observer是描述产品功能的模块
对于实现者
RI和AF相当于一个设计规范,逼着你先思考我这一个产品在实现的时候,应该使用什么数据,哪些数据是合法的,我这么设计如何给出合法输出
同时还需要考虑到,我虽然给了说明书,但客户不一定是正常人,除了我保证的正常功能之外,我还应该尽量保证我的产品不会被非法访问,不会被随 意更改,此时考虑不可变类型的数据和拷贝式防御就顺理成章了