软件构造ADT

Abstract data type

Abstraction and User-Defined Types

数据抽象:有一组操作所刻画的数据类型

抽象类型:强调作用在数据上的操作,程序员和client无需关心数据如何具体存储,只需设计使用操作即可

Classifying Types and Operations

可变和不可变数据类型

可变mutable:提供了可改变其内部数据的值的操作

不可变immutable:其操作不改变内部值,而是构造新的对象

构造器可能是构造函数或者是静态函数(工厂方法)

不可变类型没有变值器

Designing an abstract type

设计好的ADT,靠经验法则,提供一组操作,设计其行为规约spec

  1. 设计简洁,一致的操作

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

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

Representation Independence(表示独立性)

表示独立性:client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端。

spec规定了client和implementer之间的契约

要保证内部的改变对用户影响很小或基本没有

Testing an abstract data type

许多测试不可避免的相互影响

测试creator,producers,mutators:调用observers观察这些operations的结果是否满足spec

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

风险:如果被依赖的方法有错误,可能导致被测试方法的测试结果错误

Invariants

保持不变量

不变量:在任何时候总是true,例如immutability

由ADT来负责不变量,与client段任何行为无关

目的:保持程序的正确性,容易发现错误

威胁1:用户可以直接访问不变类型的filed(public)

这是一种表示泄露(representation exposure)不仅影响不变形,也影响表示独立性:无法再去爱不影响用户端的情况下改变其内部表示

解决方法 private\final

威胁2:不可变数据类型中的可变数据类型被改变

解决方法 copy这个可变数据类型避免泄露

对于任何可变数据类型,你不应该直接返回他,而是他的拷贝

如果复制代价很高,不得不直接返回,讲责任推给client,但容易引发bug

最好使用immutable类型的彻底避免表示泄露

Rep Invariant和Abstraction function

R:表示空间(开发者关注)

A:抽象值构成的空间,client看到的和使用的值(用户关注)

抽象函数:R与A之间映射关系的函数,如何解释R 中的每一个值为A的每一个值

AF:A->F(满射,非单射,未必双射)

RI:R->boolean

RI告诉我们R中的r是否被AF映射到空间A中某一个值

RI是R的一个子集

表示不变性RI:某个具体的表示是不是合法的,一个描述什么是合法的表示值的条件,所有合法的表示值

选择某个特定的表示方式R,进而制定某个子集是合法的RI,并未该自己中每一个值做出解释(AF)——如何映射到抽象空间中的值

相同的R,RI也可能有不同的AF,解释不同

设计ADT:

  1. 选择R和A

  2. RI——合法的表示值

  3. 如何解释合法的表示值——映射AF

随时检查RI是否满足

在所有可能改变rep的方法内部都要检查(Observer不用,但可以以防万一)checkRep()

Beneficent mutation

有意的可变性

对immutable的ADT,在A空间的abstract value是不变的,但在其内部表示的R空间中的取值是可以变化的

mutation改变了R值,但没有改变A值。

但这并不代表在immutable类中可以随意出现mutator

why beneficent mutation required:通过牺牲immutability的部分原则换取性能和效率

document the AF,RI,safety from Rep Exposure

在代码中用猪似的形势记录AF和RI

精确记录RI:rep中所有的fields何为有效

精确记录AF:如何解释每一个R值

safety from rep exposure :给出理由,证明代码并未对外泄露其内部表示——自证清白

ADT规约里只能使用client可见的内容来撰写,包括参数,返回值,异常等

规约中不应该谈到内部表示的细节,R空间的任何值,ADT的内部表示(私有属性)对外部应该严格不可见

在每个方法return之前,用checkRep检查不变量识别否得意保持

ADT invariants replace preconditions

用ADT不变量取代复杂的precondition,相当于将复杂的precondition封装到了ADT内部

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值