软件构造——3.2-3.3设计specification与表示泄露

3.2要求掌握

1.前置条件和后置条件的定义
2.什么是不确定性
3.什么是声名性规范和操作性规范
4.比较规格说明的强度

使用方法的用户不需要知道方法是如何工作的,我们称之为“抽象”。
行为是否等价由是否满足相同的规格说明决定。

可变方法:改变其参数(因为传入的非原始数据类型是引用)
不可变方法:返回一个新的对象,来表示对参数的修改。
如:在这里插入图片描述注意:如果没有明确说明,则默认输入值是不可变的,即该方法不通过引用对输入值进行修改(联系前面所学的可变数据类型,因为多个引用造成的表示泄露,留下安全隐患)。把这样的方法成为不可变方法。

声明性:只对输出什么感兴趣,不对怎么确定输出感兴趣。

规格说明的替换:可以用弱的或者等价的替换一个强的或等价的规格说明。
注意:下例规格说明是不正确的,太强也太弱了。
太强:一定能打开一个文件吗?有其他意外发生,不一定能打开滴
太弱:打开的文档操作权限,是可读还是可写呢?
在这里插入图片描述

选择用前置条件检查,还是后置条件检查:
前置:该方法只在类的内部调用;
后置:该方法是public 的,会被其他用户调用。

3.3ADT
ADT中,操作的分类
ADT的设计原则
Rep的独立性(RI)
ADT的测试
Rep不变量和抽象函数
用ADT不变量代替前提条件

可变数据类型:提供了可对其状态进行修改的操作;

ADT操作分类
creator:产生一个新对象,参数列表中不含要产生的对象对应的数据类型。通常以构造器和静态方法的形式出现(通常称为工厂方法)。
如:
Arrays.asList(),String.valueOf()等。

producer:在输入参数对象的基础上产生一个新的相同类型的对象。
注意:List中由原来可变数据类型产生一个不可变List的方法Collections.unmodifiableList,即为一个producer。

observer

mutator:由上面可变数据类型的定义可知,不可变数据类型没有mutator的方法
注意:String因为是不可变的,其中的concat , substring , toUpperCase等方法均为producer。

RI:
ADT主要是由其上的一些public方法,完成一些对抽象事物的模拟。因此ADT的一些抽象意义可以与其具体实现分离。只要满足了spec的功能上的要求和前置、后置条件描述,ADT内部的representation可以自由选择,从而也决定了不同的实现方式,这就是所说的ADT与内部表示分离,即Representation Independence(简写为RI)。

而rep invariant 中的RI是指在A的抽象空间中有实际意义的representation对应true,即RI: a->true.
abstraction functions(AF)指某个representation对应A空间中某个抽象值的映射关系。
在这里插入图片描述于是,我们将RI、AF以注释的方式记录下来。
如下图,RI中省略映射的过程中的对应true或者false,直接写出具有实际意义的representation。因为RI是在抽象空间中具有实际意义的representation,因此,representation必须满足A中的取值范围要求,即不变性。在写RI时,也要附上抽象空间中的范围。
而AF则负责写出相应representation对应的抽象意义,即AF中的值。

最后,注意creators, producers, 和mutators的后置条件中,必须进行rep不变性检查。基本地,前置条件和后置条件的rep都不能为null,否则必须让其失败。
在这里插入图片描述其实,这里的不变性指的是抽象值永远遵循不变性。如一个分数,将分子分母约去一个公因数后,仍表示同一个数,在后面的操作中遵循“不变性”。但事实上representation所指向的数或者说对象已经发生了改变。

表示泄漏:指类外部的代码可以直接修改类内部的representation.
防止内存泄漏的方法:
1.将所有的内部rep限定为private;
2.尽量使用不可变类型;
3.使用可变类型,需要返回可变类型对象时,进行防御性拷贝。
4.在creator和producer中产生时,就要满足不变性,而由于rep是private类型的,因此只要在observer返回的对象进行进行防御性拷贝,在mutator中不对原对象进行改变,转而用类似于producer的方式实现mutator。如此一来可以有效防止表示泄漏。

表示泄漏的危害:
严重威胁不变性与表示独立性,因为一方面,来自类外部的代码可以自由地对类内部的rep进行修改,影响不变性;另一方面,类内部的代码不能自由修改,否则会影响使用者外部的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值