软件构造学习心得之抽象数据类型

目录

1 抽象数据类型(Abstract types)

2 设计ADT

3 表示独立性(Representation Independence)

4 测试ADT

5 不变量(Invariants)&表示泄露(representation exposure)

6 表示不变量和抽象函数(Rep Invariantand Abstraction Function)

7 知识图谱


1 抽象数据类型(Abstract types)

传统的类型定义:关注数据 的具体表示

抽象数据类型:强调数据上的操作,不关心实现,只关心操作和使用。即:一个抽象数据类型ADT由其操作定义。

抽象数据类型强调“作用于数据上的操作”,程序员和 client无需关心数据如何具体存储的,只需设计/使用操作即可。需要注意的是,ADT是由操作定义的,与其内部 如何实现无关。这一点与我们要介绍的表示独立性有着重要的关系。

对抽象数据类型可以进行如下分类:

  • 可变类型对象:提供了可以改变内部数据的值的操作
  • 不可变类型对象:没有任何一个操作可以改变对象内部值

对于ADT来说,同样遵循我们之前介绍的可变与不可变类型的分类。

对于每一个ADT,其内部操作都可以划分为四类中的一种,具体分类依据如下:

  • 构造器Creator:从无到有,接受一个其他类型的参数(可无参数),生成一个该类型的ADT。构造器有两种实现方法,一个是构造函数constructor,一个是静态函数static method
    (工厂方法factory method)
  • 生产器Producers:从有到新。接受一个其他类型参数(可无参数),在原有的该ADT的基础上生成一个新的该ADT。如String的concat方法,接受两个字符串作为参数,然后拼接产生一个新的字符串
  • 观察器Observers:观察器接受一个ADT,并返回一个不同类型的对象(ADT的某些属性)
  • 变值器Mutators:改变ADT的属性
    如果返回值为void,意味着必然改变了某些内部状态,属性
    如果返回非空类型,有一些额外作用,或者用来判断是否改变成功

2 设计ADT

设计一个好的ADT有如下几个原则:

  • 简洁,一致:类中的每个方法应该对每种情况都适用
  • 满足支持client的所有操作需求,低难度:对象每个需要被访问的属性都能被访问到
  • 抽象和具体分离:抽象的类不应该设计属性的特殊性
     面向具体应用的类型不应包含通用方法 
     面向通用的类型不应包含面向具体应用的方法

3 表示独立性(Representation Independence)

client使用ADT时无需考虑内部如何实现,ADT内部表示的变化不应该影响外部spec和客户端。通过前提条件和后置条件充分刻画 了ADT的操作,spec规定了client和implementer之间的契约,明确了client知道可以依赖哪些内容,implementer知道可以安全更改的内 容。即,不管ADT具体怎么实现,client在使用该ATD时只能用规约给定的方法访问,这样程序员在实现时,就可以独立的使用自己想使用的方法,不会出现不同实现方法导致客户端无法正确执行,独立的意义正在于此。

4 测试ADT

对于ADT的测试主要分为两个部分:

  • 测试creator,producetor,mutators,调用observers
  • 测试observers,使用creators,produces,mutators来产生和改变对象

5 不变量(Invariants)&表示泄露(representation exposure)

表示不变量:ADT需要始终保持其不变量。

不变量:程序任何时期总是true的性质                                                                                                              eg. Immutability。这一点需要由ADT确保,即开发者确保。

表示泄露:client直接调用ADT内部的变量导致表示泄露。表示泄露一方面肯会影响不变量,另一方面影响表示独立性,因为外部client与ADT内部实现进行了绑定,无法在不影响外部的情况下修改内部实现。只要外部client能够通过非mutator方法改变内部表示(变量等),就存在表示泄露

6 表示不变量和抽象函数(Rep Invariantand Abstraction Function)

几个重要概念:

  • R:表示空间,表示值构成的空间,实现者看到和使用的值
  • A:抽象空间,抽象值构成的空间,抽象空间,用户能看到的样子
  • AF(抽象函数):描述的是R和A之间的映射关系的函数,即,如何将R中的每一个值解释为A中的每一个值AF:R → A,一定满射,未必单射,未必双射。当R中的值非法,则没有对应的解释使之映射到A
  • RI(表示不变量):一个条件,描述了什么是合法的表示值,也就是说,变量的那些值是可以映射到抽象空间的
  • CheckRep:用来检测表示不变量,在所有可能改变表示不变量RI的方法结束返回前都要进行CheckRep(即:在所有改变内部rep(变量)的方法中都要check)
    Observer方法可不用
    形式:
    private void checkRep(){
           assert expr-test
    }
  • 文档:

    在实现的过程中,在代码中用注释形式记录AF和RI :1.要精确的记录RI:rep中的所有fields何为有效  2.要精确记录AF:如何解释每一个R值  3.表示泄漏的安全声明 :给出理由,证明代码并未对外泄露其内部表示——自证清白 

构建一个ADT的流程:

  1. 选定某个表示R
  2. 指定某个合集(子集)是合法的,RI
  3. 为该子集的每个值做出解释,即构造AF

7 知识图谱

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值