數據抽象

目錄:

1.複合數據html

2.數據抽象ide

3.抽象壁壘函數

 

數據抽象

複合數據:將多個數據綁定在一塊兒,如日期、經緯度。spa

函數爲數據的表示與操做構建抽象壁壘的方法論。code

數據抽象容許咱們將符合數據視做操做的基本單位。htm

數據抽象將數據的表示與操做分離開:blog

-單個數據如何表示爲一個總體(as parts)it

-做爲一個總體的數據如何進行操做(as unit)io

實例

以程序來表示分數間的各類操做(假設分子和分母都爲正整數)class

首先,分數由兩部分組成,numerator(分子)和denominator(分母),其爲一對數值,即複合數據。寫做:

要對兩個分數進行運算,必須對其分子和分母進行相應操做。

那麼如何表示做爲總體(unit)的分數與部分的分子與分母?其實現暫且不論,就結果來看,要實現的是這樣一種效果:

rational函數返回一個分數

number和denom函數分別返回這個分數的分子與分母

由於rational是構造分數的方法,所以稱之爲Constructor;

numer和denom是從數據對(分數)中選擇特定部分的方法,所以稱之爲Selector。

仍舊不去管如何實現,只以此爲基礎完成基本操做。(這裏只實現加、乘、比較相等與格式化打印的操做)

圖示以下:

 

 

代碼

def mul_rational(x, y):
    return rational(numer(x) * numer(x),
                    denom(x) * denom(x))


def add_rational(x, y):
    nx, ny = numer(x), numer(y)
    dx, dy = denom(x), denom(y)
    return rational(nx * dy + ny * dx, dx * dy)


def equal_rationals(x, y):
    return numer(x) * denom(y) == denom(x) * numer(y)


def print_rational(x):
    print(numer(x), '/', denom(x))

接下來咱們再完成各個函數的實現

首先咱們先以形如[n, d]的列表形式表示分數

代碼

from fractions import gcd

# 以列表表示分數
# Constructor
def rational(n, d):
    g = gcd(n, d)
    return [n//g, d//g]

# 由分數求得分母
# Selector
def numer(x):
    return x[0]


# 由分數求得分子
# Selector
def denom(x):
    return x[1]

若是換一種分數的表示方式呢?此次用函數來表示一個分數,以特定參數調用函數表示分母和分子。

即使改變如此之大,高一層的抽象,即分數間的操做是不用作任何改變的,要改變的只是分數及其部分的表示形式。

代碼

# 以函數表示分數
# Constructor
def rational(n, d):
    def select(name):
        if name == 'n':
            return n
        elif name == 'd':
            return d
    return select


# Selector
def numer(x):
    return x('n')


# Selector
def denom(x):
    return x('d')

 

抽象壁壘

以上的代碼中,用兩種方式實現了分數及其部分的實現方法,但建諸其上的分數操做卻徹底不用改變。

這裏就涉及到了抽象的層級。在當前問題的語境內能夠分隔出如下的抽象層級:

 

各抽象層級間的粗線表示抽象層級間的壁壘。在實現程序時,不要實現去作跨越層級的操做,以下圖:

這樣會使程序的抽象結構慌亂不堪,程序也因之變得脆弱。一旦要對某一部分進行修改,整個程序都會再也不穩定。

 

參考

https://cs61a.org/assets/slides/10-Data_Abstraction_1pp.pdf

http://composingprograms.com/pages/21-introduction.html

《改變:問題造成和解決的原則》中關於第二序改變的論述

相關文章
相關標籤/搜索