[HIT软件构造Blog007]Abstract Data Type (ADT)

Abstraction and User-Defined Types

  • 除了编程语言所提供的基本数据类型和对象数据类型,程序员可定义自己的数据类型,在Java里就是类
  • 传统的类型定义:关注数据的具体表示
  • 抽象类型:强调“作用于数据上的操作”,程序员和client无需关心数据如何具体存储的,只需设计/使用操作即可
  • ADT是由操作定义的,与其内部如何实现无关

Classifying Types and Operations

  • 可变和不可变数据类型
    – 可变类型的对象:提供了可改变其内部数据的值的操作
    – 不变数据类型: 其操作不改变内部值,而是构造新的对象
  • 抽象类型分类
    – Creator
    – Producers
    – Observers
    – Mutator

Abstract Data Type Examples

在这里插入图片描述

Designing an Abstract Type

  • 设计好的ADT,靠“经验法则”,提供一组操作,设计其行为规约 spec
  • 设计简洁、一致的操作
  • 要足以支持client对数据所做的所有操作需要,且用操作满足client需要的难度要低

Representation Independence

  • 表示独立性:client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端
  • 除非ADT的操作指明了具体的pre-和post-condition,否则不能改变ADT的内部表示——spec规定了client和implementer之间的契约

Testing an Abstract Data Type

  • 测试creators, producers, and mutators:调用observers来观察这些operations的结果是否满足spec
  • 测试observers:调用creators, producers, and mutators等方法产生或改变对象,来看结果是否正确
  • 风险:如果被依赖的其他方法有错误,可能导致被测试方法的测试结果失效

Invariants

  • 不变量:在任何时候总是true
  • 由ADT来负责其不变量,与client端的任何行为无关
  • 总是要假设client有“恶意”破坏ADT的不变量—defensive programming
  • 表示暴露
    – 不仅影响不变性,也影响了表示独立性:无法在不影响客户端的情况下改变其内部表示
  • 保持不变性和避免表示泄漏,是ADT最重要的一个Invariant

Rep Invariant and Abstraction Function

在这里插入图片描述

  • ADT开发者关注表示空间R,client关注抽象空间A
  • R→A 满射
  • 抽象函数
    – R和A之间映射关系的函数,即如何去解释R中的每一个值为A中的每一个值
    – AF : R → A
  • 表示不变性
    – 某个具体的“表示”是否是“合法的”
    – RI : R → boolean
  • 选择某种特定的表示方式R,进而指定某个子集是“合法”的(RI),并为该子集中的每个值做出“解释”(AF)——即如何映射到抽象空间中的值
  • 即使是同样的R、同样的RI,也可能有不同的AF,即“解释不同”
  • 设计ADT
    – (1) 选择R和A
    – (2) RI — 合法的表示值
    – (3) 如何解释合法的表示值 —映射AF

Beneficent mutation

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

Documenting the AF, RI, and Safety from Rep Exposure

  • 在代码中用注释形式记录AF和RI
  • 要精确的记录RI:rep中的所有fields何为有效
  • 要精确记录AF:如何解释每一个R值
  • RI:针对Rep的每一个field以及多个fields之间的关系,进行条件限定,要精确
  • AF:给出client看到的A值是什么,是对每一个Rep值的“数学运算”
  • ADT的规约里只能使用client可见的内容来撰写,包括参数、返回值、异常等
  • 如果规约里需要提及“值”,只能使用A空间中的“值”
  • ADT的规约里也不应谈及任何内部表示的细节,以及R空间中的任何值
  • ADT的内部表示(私有属性)对外部都应严格不可见
  • 在对象的初始状态不变量为true,在对象发生变化时,不变量也要为true
  • Creators和Produces在创建对象时要确保不变量为true
  • Mutators和Observers在执行时必须保持不变性
  • 在每个方法return之前,用checkRep()检查不变量是否得以保持
  • 表示泄漏的风险:一旦泄露,ADT内部表示可能会在程序的任何位置发生改变(而不是限制在ADT内部),从而无法确保ADT的不变量是否能够始终保持为true

ADT invariants replace preconditions

  • 用ADT不变量取代复杂的Precondition,相当于将复杂的precondition封装到了ADT内部
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值