PHP 板


LINE

看板 PHP  RSS
聊過了類別的封裝,我們要繼續實例討論物件導向的第二特性, 也就是所謂擴充的能力。 這有點像是在玩遊戲, 假設你在遊戲裡操作著一隻小豬,這隻小豬有一個特技叫做「吃」, 每次當你遇到某個謎題時,都必需讓小豬「吃」的能力成長, 可能需要吃鐵,吃火,吃土…等等, 而每當你拿到一種新的「吃」的能力,小豬的封號也會隨之改變。 上面這個情景很類似我們對於物件導向擴充的描述, 讓我們繼續延伸前一篇的程式內容,把這個遊戲情景給套用進去 目前我們手上持有的是一個叫 dataHandler 的類別, 裡面一共具有三種不同的輸出方式,分別是 output_select output_list output_radio 仔細想想,每次都我們輸入資料產生出一個物件時, 實際上真正會使用到的輸出行為都只是三種中的其中一種, 那換個角度,我們是否能讓這個處理資料的類別具有合適的擴充能力? ok,沒有命題就不會有 fu,我們需要一個假設性的命題, 如果當你在執行這個案子的時候,你敏銳的觸感神經已經預計到, 客戶很有可能又額外提出六種輸出方式和三種統一驗證, 那這個時候要做什麼就很明確了, 我們需要這個類別具有輸出上的可擴充性,套用故事裡的情境, 也就是這個小豬(類別),需要可以增加不同的吃(輸出)的能力。 當然最簡單的方法就是增加類別內的 output_* 函式, 反正客戶要幾個就加給他幾個, 但也可以這樣思考,我們有沒有可能把整個擴充方式從扁平改成立體? 既然現在面對的擴充是針對「輸出」這件事, 那就來規規矩矩把輸出部份給抽象化, 於是原本的類別會變成: class dataHandler { var $_data = Array (); function __construct ($data) { (省略) } function data_remove_sexy () { (省略) } function data_check_add_admin () { (省略) } function output () { // 空的 } } 仔細看,三種不同的 output 此刻只剩下一種, 而且這個 output 函式還是個貨真價實的空蕩蕩的函式,裡面沒有半行程式碼, 為什麼呢? 因為我們要從原本「在類別內的橫式擴充」, 改成「藉由類別衍生所產生的直式擴充」, 剛剛上面這個 class dataHandler 其實只是一個初始類別, 真正可以拿來使用的會是下面這三個子類別: class dataHandler_OutputSelect extends dataHandler { function output () { // 輸出 select 的程式碼 } } class dataHandler_OutputList extends dataHandler { function output () { // 輸出 list 的程式碼 } } class dataHandler_OutputRadio extends dataHandler { function output () { // 輸出 radio 的程式碼 } } 如果你需要進行一個 select 輸出,你會這樣使用: $data = mysql_fetch_* ($sql); $dh = new dataHandler_OutputSelect ($data); $dh->output (); 如果今天是一個 radio 輸出,你會這樣使用 $data = mysql_fetch_* ($sql); $dh = new dataHandler_OutputRadio ($data); $dh->output (); 我知道板友們一定會開始有種被騙的感覺,這跟 $dh->output_select () 和 $dh->output_radio () 的作法有什麼不同?而且感覺還多寫了一堆 code(額外三個 class)! 請容小弟解釋一下,這兩種不同作法當中存在著很巨大的差異, 其一是這樣的程式在擴充上會更清楚明瞭, 因為往往一個類別不會只有單個函式需要做擴充, 如果同一個類別內存在著一堆相似又不同的函式,那真的是閱讀和維護上的痛苦。 其二是這樣的作法讓物件本身操作具有了一致性, 只要是 dataHandler 的子類別, 你永遠知道它具有一個關鍵的函式是 output,而且可以毫不猶豫地呼叫它, 這點非常重要,但我們會在下一篇裡面再來詳談, 因為也就是垂直擴充的物件具有了操作的一致化,第三個物件導向特性才得以成立 其三,則是一個比較難以理解的概念,那就是「決策點」的不同, (這部份如果看不懂也沒有太大關係,因為需要有經驗才比較能體會) 如果要打個比方,「決策」的概念比較像是籃球賽裡面, 你有整整 30 秒可以出手,跟被強迫在最後 0 秒出手的不同是一樣的, 這樣講好了, 當我們在嘗試把一整個程式邏輯慢慢拆解成幾種類別時, 有的類別存在週期會很長,有的則是很短, 也就是說, 有些類別會在你程式一開始的時候就已經產生物件,並持續使用到最後, (最常見的就是封裝成類別的資料庫操作) 有的類別則是「當下產出物件」-「當下使用」而已, (就像是我們剛剛的資料輸出類別) 所以此時你在設計程式流程時會有兩個選擇, 從類別 new 出物件時做決策, (像決定你要使用哪一種輸出類別, dataHandler_OutputSelect 還是 dataHandler_OutputRadio) 或是在最後函式呼叫時做決策, (像決定你要使用哪一種輸出函式, dataHandler 下的 $dh->output_select 還是 $dh->output_radio) 這當中各有各的使用時機,就端看你整體程式的運作流程要怎麼設計來決定, 其中很多複雜的運用同樣也是在導入了設計模式之後才會發現的。 講到這裡,物件導向的第二特性 - 繼承也差不多講完了。 關於繼承的詳細定義和宣告方式,不熟悉的板友可以再去看一下, 這部份小弟就不贅言了。 -- 頭痛中…(炸) --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.45.241.224
1F:推 chenstin:推! 07/30 22:01
2F:推 weiyucsie:推 07/30 22:44
3F:推 roga:推 :P 07/30 22:57
4F:推 bobju:推! 07/31 10:12
5F:推 hertz:NICE 07/31 18:40
6F:推 qmo668:推! 10/02 01:47







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:WOW站內搜尋

TOP