星期五, 9月 22, 2006

物件導向

學習物件導向這麼多年來,第一次深深覺得物件導向真是妙用無窮啊。

一年之前寫的班網完全沒有使用物件,那時候因為時間壓力就只想抄短線,所以採用程序導向,想到什麼功能就塞一個函式在include裡。

隨著班網的進度逐漸向前邁進,開始加入更多的函式,開始使用暫存變數,函式間開始互相呼叫,結果那些謎一般的include檔開始變成垃圾窩,一大堆地位平行的函式,加上主檔案無盡的暫時變數、又臭又長的函數呼叫,錯綜複雜的呼叫關係,天書一般自己都讀不懂的程式碼.....

套用物件導向有什麼好處?好處實在多太多了。

物件導向第一個好處,主檔案是主檔案,物件是物件,譬如把驗證使用者登入和Session控制的功能寫成一個物件,那麼原本要進行使用者登入、控管的主要檔案負擔就會輕很多。而且負責登入的頁面只需要把介面畫出來還有把收到的參數丟給物件,而物件只要負責處理傳進來的參數。如此一來,負責登入頁面的程式碼就只有介面的部份,而驗證物件則只有負責驗證物件的程式碼和變數,兩種不一樣的程式不會相互混雜,只透過容易理解、除錯的簡單介面相互溝通。程式從原本的「一坨」變成兩個均質的純物質,除錯、變更工作變得更為輕鬆。

反之,那種堅持不要用物件,堅持採用「我只要把不同類方法放在不同檔案就可以了」的人,即使勉強可以把方法移出呼叫者的檔案,但呼叫用的參數和暫時變數仍然不可能弄走,結局就是程式還是很混亂,至少至少「很多亂七八糟的變數」混合在一起的情況無法避免。

物件導向第二個好處,「物件」這種東西可以重複利用,寫程式的人,永遠不知道上頭要叫你實做什麼新功能。上頭心血來潮,吾人鞠躬盡瘁。愛用物件導向的人,隨時可以從物件之中抽出物件,什麼?上頭要交代的新功能和我們原有物件的功能類似,可是程式碼有很多細部不同?沒關係,吾人可以從現有的物件之中抽出共同的抽象物件,然後讓新的物件繼承原有的抽象物件,照樣可以快樂的實做。要擴充現有的功能?沒關係,創造新物件繼承舊物件,程式不必改太多,上頭的要求照樣快樂達成。

反之,程序導向的基本教義派這時候就會卡關,物件有繼承,可是方法沒有繼承,這時只能出動傳說中的複製貼上,讓原本已經混亂無比的函數世界加入更多的動盪不安,更難除錯,更多暫時變數。當未來不斷進行修改的時候,還容易改出怎麼抓都抓不到錯的怪程式。而且方法不能像物件一樣進行late binding,所有的重擔都壓在呼叫方法的那邊,所以程序導向的程式常常會有長串的switch或if,維護性只會隨著時間越變越差。

物件導向第三個好處是可以利用public、protected、private等關鍵字進行封裝。程式員可以把「物件」想像成「家族」,然後對每個資料和方法進行個別的設定,敏感性的資料可以設定只有同一家的才能存取,內部的「骯髒方法」可以禁止外部隨便呼叫。結果就是物件和外界可以互動的「接觸面積」大幅減少,程式自然比較不容易亂。


物件導向的「繼承」廣義而言並不只限定於狹義的父子關係繼承,「包含」也可以視為一種繼承。一個物件可以拿很多其他物件當作成員,而每個成員物件又可以拿很多別的物件當作成員,彼此之間卻因為封裝的關係,仍然顯得層次井然,容易維護、容易擴充。

比如更動課表的PHP可以包含一個「認證暨課程修改物件」,而這個「認證暨課程修改物件」可能包含很多接受呼叫用的介面函式、內部處理資料的函式、一個連接課程表的資料庫物件以及負責使用者登入控管的授權物件。而授權物件可以包含許多內部方法,可能又包含一個通往帳號密碼資料庫的資料庫物件。而資料庫物件可能包含一個Mysql連結、登入資料庫的帳號和密碼、儲存查詢結果用的暫時陣列。如果不採用物件導向,而改用程序導向來實做,那可能同一份程式碼就會有無數個不同目的的暫時變數,放密碼的、資料庫存取用的、課程相關的....以及一大堆Mysql連結,加上一大堆不同目的的函數呼叫放在一起,一下子叫資料庫,一下又存取課程表、一下又讀授權表,等會又連接新資料庫....程式想要不出錯也難。

所以想要程式好維護的看官們,下次碰到寫程式就給他來個物件導向吧!就算只有方法沒有資料也沒關係。沒有資料,以後可能有。而就算是純方法構成的物件,也可以拿來做很多好玩的事情,比如接水管(物件裡面有指向某抽象物件的指標,然後該抽象物件的抽象方法可以有很多種不同的實做,密碼學的程式庫就常常搞這種事)、或是達到更好的擴充性和存取控制、增加可維護性等等,使用物件導向能夠讓程式設計發揮到極致啊orz 全文連結

0 意見: