ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

软件构造-6 抽象数据类型(ADT)

2022-06-04 15:32:43  阅读:172  来源: 互联网

标签:抽象数据类型 ADT AF rep client 抽象 软件 RI


       正式进入复习阶段,考虑到现在正在写的Lab3与6,7,9章关联比较大,同时这三章也是比较重要的三个章节,分别涉及到了ADT,OOP和面向可复用性的编程。之前上完课之后也一直没有对这几章进行系统的复习(不过Lab2就是对ADT和OOP的实践,所以对这部分印象还是比较深的),因此首先复习这三章。

       本章介绍ADT,主要是对PPT内容的总结,会结合一些个人的理解(这部分用带下划线的字表示,可能存在一定不准确或错误的地方,个人水平原因,见谅)。

抽象数据类型(ADT)

ADT的特性:不变量、表示泄漏、抽象函数AF、表示不变量RI

基于数学的形式对ADT的这些核心特征进行描述并应用于设计中

 

1.抽象和用户定义的类型

(1)用户定义的类型:程序员可以定义自己的数据类型

(2)数据抽象:由一组操作所刻画的数据类型,不同于传统的类型定义关注数据的具体表示,抽象类型强调“作用于数据上的操作”,程序员和client只关心设计/使用操作。

Eg:设计抽象数据类型图(一个类),为其设计操作图的方法(类中的方法),比如增加顶点,在两个顶点之间增加一条边,删除一条边等等。

 

2.对类型和操作分类

(1)可变数据类型(mutable)提供可改变其内部数值的操作,比如set方法等。

(2)不可变数据类型(immutable):操作不改变内部值,而是构造新的对象,比如进行操作后返回一个由操作改变后所得的新的对象。

(3)对抽象类型的操作分类:

1>   构造器:从无到有,可能实现为构造函数或静态函数(实现为静态方法的构造器通常称为工厂方法)

2>   生产器:从有到新,比如String类型中的concat()方法,它使用两个string,并生产一个新的代表这两个string合并结果的string。

3>   观察器:获取抽象类型的对象并返回不同的类型(描述这个类的某种属性),比如List类的size()方法,返回这个List的大小。

4>   变值器:改变对象属性的方法,比如List对象中的add()方法,通常返回void,不过也可能返回非空类型。

 

3.设计抽象数据类型

(1)良好ADT的设计:靠“经验法则”,提供一组操作,设计其行为规约 spec

(2)拇指规则(经验法则):

     1> 设计一组简单操作,通过简单操作的组合实现复杂的操作。操作的行为应该是内聚的。(内聚:内聚标志一个模块内各个元素彼此结合的紧密程度,内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。)

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

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

 

4.表示独立性(RI)

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

(2)通过前提条件和后置条件充分刻画ADT的操作,spec规定了client和implementer之间的契约,明确了client知道可以依赖哪些内容,implementer知道可以安全更改的内容.(就是要为方法编写spec注释,标明@param, @return 等描述前置条件和后置条件的内容)

 

5.测试抽象数据类型

(1)测试构造器,生产器和变值器:调用观察器来观察这些操作和结果是否满足spec。

(2)测试观察器:调用其他三个方法产生或改变对象,调用观察器来看结果是否正确

 

6.不变量(Invariants)

(1)ADT需要始终保持其不变量(程序在任何时候总是true的性质),由ADT负责不变量。

(2)要假设client有“恶意”破坏ADT不变量的行为

(3)rep exposure(表示泄露):rep被泄露,可以被外部改变(防范方法:比如将rep设置为private final类型或者使用防御性拷贝,返回新的对象,或者直接使用immutable的类型)

 

7.RI和AF

(1)R和A:

          R(表示值构成的空间,开发者关注):实现者看到和使用的值,方法中的rep(representation,在类的最开头,所有方法外部定义的一般为private类型的变量)构成的空间。

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

          R到A:满射(每一个抽象值都被一些rep值映射到)/未必单射(一些抽象值被不止一个rep值映射到)/未必双射(不是所有rep值都映射到抽象值)

(2)AF(抽象函数):R和A之间映射关系的函数,即如何将R中的每一个值解释为A中的每一个值。(个人理解:一般是描述一下类中的rep是如何映射到抽象空间的(这里的抽象空间一般就是这个类所代表的抽象),比如说图这个ADT,其中的rep是顶点集vertices,那么AF可以描述为将vertices(顶点集)映射到一个有向加权图上)

(3)RI(表示不变量):比较简单易懂的理解方式是,将它看作描述什么是“合法”rep的条件。

(4)为RI和AF进行文档注释(RI,AF等注释与spec使用/*不同,它们直接使用//):

 

(这里的AF采用的是最规范的写法,进行映射函数的编写,将rep s通过AF映射到字符set上,同时使用符号语言描述了字符set。但实际书写时不需要严格满足这个规范,可以按照上面个人理解中的例子,直接文字说明rep是怎样映射到抽象类型上的即可,抽象类型不是必须用符号语言表达)

(5)设计ADT:

         1> 选择R和A;

         2> RI --- 合法的表示值;

         3> 如何解释合法的表示值 ---映射AF

(6)随时检查RI是否满足:

       根据写出的RI编写checkRep函数,使用assert检查所有所有要求是否被满足,在所有可能改变rep的方法内都要检查(调用checkRep函数),观察器方法可以不调用,建议用,以防万一。

 

8.有益的改变

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

(2)这种改变只是改变了R值,没有改变A值,对client来说是immutable的。实际上代表着AF并非单射,从一个R值变成了另一个R值。

(3)这种改变无害,甚至是有益的,但是不代表在immutabke的类中可以随意出现mutator。

 

9.为AF,RI,Safety from rep exposure编写注释

(1)RI:rep中的所有fields何为有效

(2)AF:如何解释每一个R值

(3)编写safety from rep exposure:给出理由,证明代码并未对外泄露其内部表示

标签:抽象数据类型,ADT,AF,rep,client,抽象,软件,RI
来源: https://www.cnblogs.com/redTide/p/16341951.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有