星期六, 7月 05, 2008

以 BigNumber 的概觀設計談 OO

如果你要設計一個新型別,有哪些事是你會考慮的呢?

--


撇開實作不談,最該先被考慮的是 - 「到底要提供哪些 operator」

class type 和 basic type 的差異在於:
basic type 的操作幾乎全建立在符號上(+, -, *, /, ...);而 class type 則能有類似 function call 的操作。

而以 BigNumber 的觀點來看,我們希望它操作上如同 basic type - int 般,那樣直觀。所以若能設計出建立在符號上的最基本的整數運算及 IO,這是首選。也就是說,這 class type 可以很自然透過加減乘除等符號,完成我們所要求的運算。
要實作出這樣的 type - BigNumber,必須使用有提供 operator overloading 的 programming language 才行。

若上述要求無法達成,就必須考慮類似 function call 的操作方式。
而這種方式又分為兩種:隸屬於 class 或 object 的 function,這兩者的差異可以用以下兩種 declaration 來分析。

static BigNumber add (BigNumber &n1, BigNumber &n2);

在使用上就像:

bignumber3 = BigNumber.add (bignumber1, bignumber2);

而另一種是

BigNumber add (BigNumber &big);

使用上如:

bignumber3 = bignumber1.add (bignumber2);

在這兩者的選擇上,我偏向使用前者,在使用上較於自然(很明確看出將兩個 BigNumber parameter 相加,並回傳相加後的結果 - 仍以 BigNumber 表示)

而在實作上,兩者的差異並不大,純粹看設計者偏好哪種方式。

--

說到這裡,已經顯現出 OO 最重要的特色。

在設計一個 type 之前,思考此型別該具備哪些操作,這就是 data abstraction。我們知道 BigNumber 應該具備加減乘除甚至 mod 等 operator,也考慮要以哪種方式實作這些 operator(以符號 +-*/,以 function belong to class,或 function belong to object)。

思考到此,我們已經掌握整個 type 的雛形,甚至懂得如何去使用這個 type。但「operator 是如何被設計的?」「是以何種方式去表示大數?」這些,我們都還不懂;也可以說,在實作階段前,我們不需要懂。

「實作」和「概觀」被分開了,在正式進入實作前,不希望去了解內部的結構,我們可以對它一無所知。但我們必須徹底了解 type 具備哪些 operator,該怎麼去使用等...

就好像站在使用者的角度,可以想像得到:「喔,這是個什麼樣的東西,它可以這樣被使用」,可是對「它是如何被設計出的」一概不了解。因為這些繁複的細節,對使用者來說是多餘的...

而這正是 data abstraction 的精義。

沒有留言: