天天看點

《面向對象的思考過程(原書第4版)》一1.3 過程式程式設計與面向對象程式設計

在我們深入了解面向對象開發的優勢之前,先考慮一個更基本的問題:究竟什麼是對象?這既是一個複雜的問題,也是一個簡單的問題。它複雜是因為學習任何一種軟體開發方法論都非易事。它簡單是因為人們已經在按對象的方式進行思考。

例如,當你看到一個人,你會把他看作一個對象。一個對象由兩部分組成:屬性及行為。一個人具有屬性,比如眼睛顔色、年齡、身高等。一個人也有行為,比如行走、講話、呼吸等。對象的基本定義是一個包含了資料和行為的實體。

單詞和(both)是面向對象程式設計與其他程式設計範式的核心差別。例如在過程式程式設計中,代碼放置在完全不同的函數或程式中。如圖1-1所示的理想情況下,程式即為“黑盒”(black box),接收輸入,然後輸出。資料放置在單獨的結構中,通過函數或程式進行操作。

《面向對象的思考過程(原書第4版)》一1.3 過程式程式設計與面向對象程式設計

面向對象與過程式程式設計的不同之處

在面向對象的設計中,屬性及行為包含在單個對象中,而在過程式或結構式設計中,屬性和行為通常是分開的。

雖然面向對象設計越來越流行,但有個現實問題最初阻礙了面向對象設計的推廣,那就是很多非面向對象的系統還在正常工作。是以,沒有任何商業動力來将其改造為面向對象的系統。任何熟悉計算機系統的人都知道不管對系統的修改有多小,都極可能引發災難性的後果。

同樣的情形也阻礙了采納面向對象的資料庫。随着面向對象開發方式的發展,貌似面向對象的資料庫将替代關系型資料庫。然而,這絕不會發生。關系型資料庫得到了大量的商業投資,而現有的關系型資料庫可以正常工作,這一重要因素阻礙了向面向對象的資料庫的轉換。将關系型資料庫轉換為面向對象的資料庫花銷巨大又充滿風險,但卻沒有一個足夠令人信服的理由來支援轉換。

事實上,企業已經找到了一個折中方案。當今很多軟體開發實踐糅和了幾種開發方法論,比如面向對象和面向過程方法論。

如圖1-2所示,結構化程式設計中資料往往與程式分離,而且資料是全局的,是以在你的代碼作用域之外依然可以很容易修改資料。這意味着對資料的通路是失控的,并且不可預期(因為很多功能都可以通路全局資料)。而且,由于你無法控制誰能通路資料,那麼測試和調試将變得更加困難。對象通過将資料和行為組合到一個完整的包中進而解決了這些問題。

《面向對象的思考過程(原書第4版)》一1.3 過程式程式設計與面向對象程式設計

恰當的設計

如果設計是恰當的,那麼在面向對象模型中則不會有諸如全局資料的元素。事實上,在面向對象系統中具有很高的資料完整性。

對象并不會完全替代其他的軟體開發範式,它是一種進化。結構化的程式有複雜的資料結構,比如數組等。c++有結構體,結構體具有對象(類)的很多特性。

然而,對象比資料結構體及原始資料類型(比如整型和字元串)更豐富。對象包含整型和字元串之類的實體,用于表示屬性,對象也包含方法,用于表示行為。在對象中,方法用于操作資料及其他行為。更重要的是,你可以控制對對象中成員(包括屬性及方法)的通路。這意味着某些成員(屬性和方法)可以對其他對象隐藏起來。例如,名為math的對象包含兩個整數,叫作myint1和myint2。同時,math對象也包括了必要的方法存取myint1和myint2的值。它也包括一個叫作sum()的方法對這兩個整數求和。

資料隐藏

在面向對象的術語中,資料表現為屬性,行為表現為方法。限制通路具體屬性和(或)方法的行為叫作資料隐藏。

将屬性及方法合并到同一個實體中,在面向對象中将這種方式叫作封裝(encapsulation)。我們可以控制對math對象的資料的通路。比如将這些整數定義為禁止對外通路,其他函數無法操作整數myint1和myint2,隻有math對象才行。

合理的類設計指導

請注意完全有可能建立一個設計差勁的面向對象的類,該類沒有對自身屬性的通路進行任何限制。即使你使用面向對象設計也可能會設計出爛代碼,使用其他的程式設計方法論都會有這樣的可能性。請堅持合理的類設計指導(詳見第5章)。

另一個名為myobject的對象如何擷取myint1和myint2的總和?它會詢問math對象,即myobject會給math對象發送一個消息。圖1-3展示了這兩個對象如何通過方法進行通信。該消息其實就是調用math對象的sum方法,sum方法把值傳回給了myobject。巧妙之處在于,myobject無需知道總和是如何計算出來的(盡管我認為它能猜到)。使用這種設計方法,你可以修改math對象計算總和的方式而無需對myobject做任何修改(這意味着擷取總和的方式無需改變)。你需要的是總和,而不用關心它是如何計算出來的。

我們可以通過一個簡單的電腦示例來示範該概念。當使用電腦求和時,你隻需使用電腦提供的接口,即鍵盤和led顯示器。電腦有一個求和方法,當你按下正确的按鍵序列就會調用它。你會得到正确的傳回結果,然而你無需知道結果是如何計算出來的,你既不用關心電路控制,也不用關心算法。

《面向對象的思考過程(原書第4版)》一1.3 過程式程式設計與面向對象程式設計

求和不是myobject的責任,它是math對象的責任。由于myobject可以通路math對象,它可以發送相應的資訊并擷取正确的結果。通常,對象不應當操作其他對象的内部資料(即myobject不應當直接修改myint1和myint2的值)。而且随着持續開發,最好多建構一些具有明确任務的小對象,而不應該建構包含很多方法的大對象。