PHP面向對象之我見

        (本文於2010.10.01發表在《草根》雜誌第四期,LAMP交流超級羣(500人):106382633)        
        PHP由Sapi、Main、Zend和Ext組成,PHP應用由哪些組成?地基+上層建築。所謂地基就是各個應用間共有的那些部分,像現在流行的很多PHP框架就是試圖給你打個地基。我不大喜歡別人給我打地基,所以平時都是自己打地基,自己打的地基牢與不牢自己最清楚。我爸是個建築家,他建房子的能力在我們小鎮也是赫赫有名了,從小耳濡目染,導致我也對打地基搞建築很感興趣,現在把這股勁弄到打軟件地基上來,看能打出個啥地基出來,嘿嘿。
        這個地基應該怎麼打?說實話這非常依賴經驗。純理論派的傢伙,別看他口若懸河講起理論來滔滔不絕,你一讓他給你寫一個出來看看,他立馬消失;純實戰派的傢伙怎麼樣,對比想象一下便知,在此不在廢話。我不喜歡蠻幹,所以我推崇的是中庸之道:理論與實踐相結合。
看過一堆框架後相信很多人多少都對什麼控制器、視圖、模型之類的東西有點熟悉了,在此也不多說。我想說的是,把眼光放遠一點,放靈活一點,放實際一點。又遠又實際?這不是矛盾麼?那可未必。面向對象是不是較新的開發方式?看着那麼多粉絲前撲後繼“奔向”軟件開發的“真理”,我倒開始打退堂鼓。當然,你可以認爲我面向對象能力不過關:)然而翻開《人月神話》,感受一下真正的大師對面向對象開發方式的淡然的態度,我忽然覺得以前對面向對象開發的狂熱是多麼幼稚……
        實際上我想說的是,面向對象不過是一種普通的軟件開發方式,而且它的名字取得很莫名其妙,什麼是“面向”對象?爲什麼是“面向”而不是“背向”?這很滑稽,所以我寧願稱之爲“對象化”編程,以跟“結構化”編程相對應。對象又多少種呢?在PHP裏,基礎設施大部分是地基對象。注意,我說的是“對象”,而不是“類”。我很反感討論對象時把類扯進來。PHP程序的一次運行就像一個士兵到一個城堡內送一封信,得到城主的處理後把結果送回,從進城門到出城門這一過程就是PHP腳本的執行過程。它的本質就是“過程”,不認識這個本質的設計註定是失敗的。這個過程你會怎麼設計?這就跟打基礎一樣啦。你會想,可能會有兩個士兵守城門,進了城門後有嚮導,嚮導會問你有什麼事,然後告訴你怎麼走,走到目的地後又有士兵攔住你要證明,通過證明後才讓你進入辦事處,然後纔是實際的事務,完成事務後一路返回,向各個守衛告別,最後離開城門:整個過程就是PHP腳本的執行過程。
        發覺我經常走題萬里,看,什麼是靈活一點什麼是實際一點,怎麼打地基,都跑九霄雲外去了,抱歉抱歉。實際上靈活、實際等概念跟其它衆多優秀設計理念完全是融合在一起的,不好單獨抽出來說明而不涉及其它概念,但基於這些互相融合的概念,設計出來的系統卻是非常靈活的系統,具有非常低的互相糾纏關係,用術語說,是“耦合”關係。“零件”是極富表現力的隱喻,一個系統的動作都是由零件組織起來的。OK,回到城堡的例子,前面說的守衛啊,嚮導啊就是各種各樣的零件。零件需要“類”嗎?直接來看,不需要,它們各成自的職責,管它什麼類不類。當你真正需要具有相 同職責的多個零件時,你才真正需要類。我認爲就php的執行模式來看,它應該添加一個編程元素:對象,然後賦給它各種修飾,如抽象對象 啦,抽象接口啦,等等。偏偏PHP那班開發人員死腦筋,一味只知道照搬其它語言的概念,對“建設有PHP特色的編程模式”沒有衝勁。
        好了,不再瞎扯了:)回到城堡上來。剛進門需要一個人接待你,不管你要什麼,你總是要進門的嘛,所以初始檢查就是這個守衛的責任了,放在PHP裏,就是所謂的index.php,所有的請求統一由它來接收。這個守衛要做些什麼,有哪些職責,都需要你這個設計師來設計。如果這個人不符合進門標準,那麼不好意思,只能請你回去了,呵呵。如果通過了檢查,守衛可能要根據你的要求來選擇爲你服務的後續人員,比如你只認識英文,那我當然要給你佈置英文環境了,呵呵。嚮導又做什麼呢,它要根據你想去的目的地爲你指路,所以它需要知道你的目的地,和一張城堡地圖。如果在城堡地圖裏找不到你要去的地方,那麼sorry,您來錯地方了,地圖是一件公有物品,因爲如果有誰要告訴這個衛兵另一個目的地的話,它都必須是在地圖裏明確標明的一個地方。對比到PHP裏,你很容易就能知道這是一個dispatch+route的過程,呵呵。所以開發這些名詞的那些傢伙也只是借了些隱喻而已,沒什麼大不了的,只要你想象力豐富,你完全可以顛倒這個一般的城堡規則,按你的意思來構建屬於你的城堡規則。
        指令操作數據這種方式,跟數據本身具有綁定的指令這種方式,有什麼本質的區別?沒有質的區別。你可能會跟我說在認知上有區別,對,但這種區別我認爲並沒有想象中的那麼大,只是把主動權倒了一下而已,並沒有多少神奇的能力和效果。面向對象編程實在是被吹得太過了。
        不覺得?再看看《領域驅動設計》裏的服務。你覺得服務操作實體是不是跟指令操作數據非常相像?這是一個非常大的諷刺,面向對象的終點,卻是它們所不屑的“指令操作數據”的編程方式!嗚呼,“面向對象技術並沒有給我們帶來‘神奇的效應’,不管開發商如何吹噓面向對象OO(Object-Oriented)工具是多麼萬能,也不管那些OO狂熱者是多麼毅然地前赴後繼,這方面的數據從20世紀80年代以來並沒有發生大的改觀”。
反觀目前的PHP框架,有多少是遵循了軟件設計和對象式編程的精髓呢?很遺憾,沒有。Zend Framework?不客氣地說,它連幼兒都算不上,還只是個嬰兒,而且是個委員會產品,跟軟件藝術相差幾萬光年。
        我不喜歡在領域層亂搞對象,這樣你只會給自己帶來麻煩,你很難靈活地把它們保存到數據庫中。雖然我不喜歡過早優化,但即便是不優化,對象映射到關係也是件很麻煩的事情,如果再需要爲了性能進行數據庫重構,引入各種不合關係數據原則的修改,則情況會更糟。軟件開發的首要使命就是降低複雜度,對象關係映射卻成功地把複雜度提高到了一個新的高度。當然你熟悉了ORM,小系統開發起來非常快,但不要把這套經驗照搬到大負載系統裏來,這樣你會死得很慘。
        再看看ROR,它現在已經爲了迎合所謂的“企業級應用”而“成功地”變得越來越複雜,等着看它被徹底拋棄吧。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章