软件构造总结---ADT

一、抽象数据类型
1.ADT相关概念
抽象数据类型是一种不同于编程语言所提供的基本数据类型,用户自己定义的数据类型,例如类等。本质上ADT是由操作定义的,与其内部如何实现无关!

可以讲ADT分为可变的与不可变的数据类型:

可变类型的对象:提供了可改变其内部数据的值的操作,如StringBulider
不可变数据类型: 其操作不可改变内部值,而是构造新的对象 ,如String

对于ADT的操作,可以大致分为四类:

Creators:构造器(从无到有)  t* → T  可能实现为构造函数或静态函数

Producers:生产器(从有到新)   T+, t* → T  如 String.concat()

Observers:观察器 T+, t* → t   如 List.size()

Mutators:变值器,改变对象属性的方法 T+, t* → void | t | T  如果返回值为void,则必然意味着它改变了对象的某些内部状态

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

2.要足以支持client对数据所做的所有操作需要,且用操作满足client需要的难度要低 

3.要么抽象、要么具体,不要混合 ---要么针对抽象设计,要么针对具体应用的设计

二、表示独立性
1.表示独立性
我们称类中的具体属性为该抽象数据类型的表示,表示独立性的核心含义就是要达到使用效果与表示相独立,互不依赖。client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端。

2.测试ADT
1.测试creators, producers, and mutators:调用observers来观察这些operations的结果是否满足spec; 

2. 测试observers:调用creators, producers, and mutators等方法产生或改变对象,来看结果是否正确。 

注意:测试时,对于自定义ADT需要重写equals和hashcode,后续会有讲解。

三、不变量
1.不变量
不变量就是程序在任何时候总是true的性质,由ADT 来负责其不变量,与client端的任何行为无关,可以保持程序的“正确性”,容易发现错误。

我们需要注意,防止表示泄漏,不仅影响不变量,也影响了表示独立性。当代价很高时可以在规约中做出相应规定,实际上最好的办法还是使用不可变数据类型。

2.表示不变量与抽象函数
我们可以将一个程序抽象成一个由实现者看到和使用的值R到使用者看到和使用的值A的一个映射:AF : R → A,其中R叫作表示空间,A叫作抽象空间。显然R->A一定是满射但未必单射、未必双射。

表示不变性RI:某个具体的“表示”是否是“合法的” 

也可将RI看作是所有表示值的一个子集,包含了所有合法的表示值 

也可将RI看作是一个条件,描述了什么是“合法”的表示值

总之,RI作用就是描述了R中合法的表示

同一个ADT,可以有多种表示;不同的内部表示,需要设计不同的AF和RI;同样的表示空间R,可以有不同的RI; 即使是同样的R、同样的RI,也可能有不同的AF,即“解释不同”。
 

所以我们在设计ADT时需要:

(1) 选择R和A;

(2) RI ---合法的表示值;

(3) 如何解释合法的表示值 ---映射AF;

(4) 做出具体的解释:每个rep value如何映射到abstract value,而且要把这种选择和解释明确写到代码当中,以注释的形式(注意,不能以规约的形式,因为规约是可以暴露给客户端的,如果把RI和AF暴露给客户端,这也是一种表示泄露);

(5)  在所有可能改变rep的方法内都要检查是否破坏了表示不变量,可以用checkRep函数的形式;

(6) 构造器和生产器在创建对象时要确保不变量为true ;变值器和观察器在执行时必须保持不变性。

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值