2.1.2 抽象隔离

2.1.2 抽象隔离
在继续关于复合数据和数据抽象的更多的例子之前,让我们考虑一些由有理数例子
产生的一些问题。我们定义了有理数的操作,是用make-rat和numer,denom.
总之,数据抽象的根本思想是为每种数据对象标识出一个基本的操作集合。
这个集合能把那种类型的数据对象的所有的操作都表达出来,然后仅使用
那些已定义的操作来操作数据。

   我们能够重审视一下有理数系统的结构。见图2。1
横线表示抽象隔离,实现的系统的不同的层。在任何一层,隔离都分离出
上面的程序和下面的程序。上面的程序使用数据抽象,下面的程序实现数据抽象.
使用有理数的程序在操作有理数时,仅使用有理数软件包中的为公共使用的
接口程序 add-rat,sub-rat,mul-rat,div-rat,equal-rat?.
这些接口程序,相反地是被组合对象的程序和选择对象属性的程序实现的。
而这些操作对象的程序是被数对的程序实现的。数对如何实现的细节与有理数软件
包的其它部分是不相关的,只要数对能被正常使用即可。
在效果上看,任何一层的程序都是定义抽象隔离和连接不同的层次的接口。
-------------使用有理数的程序-------------
             有理数在问题域
-------------有理数的操作 例如加法减法 add-rat sub-rat -------------
              有理数作为分子与分母
-------------有理数对象的操作 例如组装对象,得到对象属性 make-rat numer denom-------------
               有理数作为数对
-------------数对的操作 cons car cdr-------------
               数对怎么被实现

这个简单的思想有很多的好处。一是它使程序更容易维护和修改。
一种编程语言提供的原生的数据结构有多种方式来表达出任何复杂的数据结构。
当然了,表示方式的选择影响了程序对它的操作,因此,如果在稍后的时候,
表示方式被改变,程序可能不得不进行相应的修改。如果没有对表示方式的依赖
通过设计一些程序模块来进行有效的限制的话,这种任务很耗时,
在大型程序中成本太高了。

例如,对于把有理数化简成最简形式的问题的一种可行的方式是
当我们取有理数的一部分时进行化简,而不是在我们组装有理数时.
这会形成不同的组装程序和选择子程序.

(define (make-rat n d)
  (let ((g (gcd n d)))
   (cons (/ n g) (/ d g))
   )
)

(define (make-rat n d) (cons n d))

  (define (numer x)
    (let ((g (gcd (car x) (cdr x))))
         (/   (car x) g)
    )
)

(define (denom x)
  (let ((g (gcd (car x) (cdr x))))
       (/ (cdr x) g)
   )
)

这种不同,取决于我们计算最大公约数的时机. 如果在我们的使用中,
我们要存取有理数的分子和分母很多次时,当有理数组装时计算最大公约数,更好一些.
如果不是这样,我们可能更愿意在取分子分母时计算最大公约数.
在任何一种情况中,当我们从一种表示法改成另一种时,程序add-rat,sub-rat等程序
都不用进行任何修改。

对一些接口程序的表示法的依赖的限制,帮助我们设计程序并能修改它,
因为它允许我们在考虑可选的实现方面,保持了灵活性。
为了继续用这个简单的例子,假定我们设计了一个有理数的软件包,
并且我们没有决定在初始时是在组装时还是在取数时执行最大公约数的计算。
数据抽象的方法论给了我们一种方式,能够延迟做决定,却没有
耽误系统的其它部分的开发。

练习2。2 考虑一个在平面上表示线段的问题。任何一个线段,都能被表示成
一个点的数对。一个起点和一个终点。定义一种组装子 make-segment  和
选择子 start-segment 和 end-segment,即用点的术语来定义线段的表示。
进而,一个点能被表示成一个数的数对,有X坐标和Y坐标。相应地,指定一个
组装子make-point和选择子x-point 和y-point 来定义这种表示。
最后,使用你的组装子和选择子,定义一个程序midpoint-segment,参数是一个线段,
返回一个中点(它的坐标值是起点与终点的坐标值的平均值)。在你的程序中,
你需要一种打印点的方式。

(define (print-point p)
   (newline)
   (display "(")
   (display (x-point p))
   (display ",")
   (display (y-point p))
   (display ")")
)  

练习2。3 在一个平面上实现一个矩形。提示你可能要用练习2。2的代码。
使用你的组装子和选择子,创建程序来计算给定程序的周长和面积。
现在实现一个矩形的不同的表示。你能设计你的系统有合适的抽象隔离吗,
为了实现相同的周长和面积计算程序能够使用不同的矩形表示而正常工作吗?

猜你喜欢

转载自blog.csdn.net/gggwfn1982/article/details/81427786
今日推荐