PHP 實踐 mix-in 概念之可行性
最近在學習 Ruby 的過程中,接觸到'Mix-in' (混成) 這個新名詞。雖然是個新名詞,但其概念嚴格說來並非 Ruby 所獨有。
Mix-in (混成) 之基本概念在令行為抽象化,使其與特定類別或實例無關。我們再將這些抽象行為組成新的類別或個體。早期的模組化編程概念,其實就已經建立了這種概念, Ruby 則是聰明而有效結合模組與類別,增加許多設計彈性。
Ruby 可以這麼做,那其他語言呢? C/C++ 自然不用說,事實上, C/C++ 可以深入到系統層級實現任何程序員想做的事。說到這就扯遠了,我們當然希望在語言層級上實現混成概念。我想想, JavaScript 可以,那麼 PHP 呢?這篇文章的標題可還寫著 PHP ,當然要談。
說明 PHP 能否實踐混成(mix-in)概念之前,我們先來看 JavaScript 怎麼做?
Invoking variable function without access object context
儘管 PHP 沒有函數指標、函數個體等功能,但藉著以「名」參照的方式,我們可以使用 Variable function 。自 PHP3 以來的長久時間中,我們一直藉 Variable function ,享受動態的函數調用技巧。那麼它能否實踐混成概念呢?首先我們先看一段基本程式。
首先,我定義了一個獨立的函數bar1
。接著定義一個類別O
,其中以 __set
指派要混成行為的函數名稱,再以 __call
調用混成的行為。結果證實這是可行的,我們心裡可以先竊喜一下。
How about access object context
不要高興太早,函數bar1
並沒有嘗試存取任何個體成員,它是一個完全獨立的函數。我們目前只證明它可以混成為類別行為。所以接下來我們要嘗試這樣的函數能否存取個體成員,就像開頭那個 JavaScript 程式所做的事一樣。
一拍兩瞪眼,廢話不多說。從bar2
到 bar4
都發生錯誤。 PHP 的錯誤訊息很明顯地告訴我們,$this 關鍵字不能用在類別以外的函數中,這不像 JavaScript 的 this 會自動依情境指涉關聯個體。
儘管如此,函數bar4
的錯誤訊息卻透露出了一絲絲曙光,它的訊息是不允許存取成員。這不難想像,畢竟我們宣告該成員為 private ,所以外部函數無法存取。但有 C/C++ 經驗的程序員這時應該聯想到夥伴函數(friend function) 了,如果我們宣告函數bar4
為類別的夥伴不就能存取了嗎?遺憾的是, PHP 不提供夥伴宣告功能,所以目前暫時做不到。
Access public member of instance
外部函數不能存取受保護的成員,又不能宣告為夥伴,那麼退一步想吧,只要是公開成員就可以做到了吧。
類別O2
與O
類似,差別在其$name為公開成員。這一次終於可行了。
到目前為止,雖然 PHP 已經具有比 Java/C# 更良好的設計彈性,但作為一個動態語言還有許多地方需要改進。暫且先期待 PHP6 的成長吧。
相關文章
- 類別繼承、介面宣告與模組混成(mix-in)
- Delegate in C# and Module in Ruby
- PHP 實踐 mix-in 概念 part 2 - MixableClass
- PHP 5.4 新功能
樂多舊回應