一般對於Util方法,不外乎下面幾種方法,以及我的一點看法:
- 依賴注入(好,但麻煩,且Util似乎與注入對象的主業關係不大)
- 弄一個包含Util方法的Container,然後注入(比上面那個只好一點點)
- 靜態方法(static is evil)
PHP 5.4 引入了 Trait,一般來說,用它作為 Interface 的預設實現似乎受眾比較多。
用 Trait 來匯入 Util 函數肯定是可行的,但這種解決方案是否違背 OOP 原則?是否最佳或者“優雅”呢?我舉個例子:
Trait FormatDatetimeTrait{ proteted function formatDatetime($datetime, $style) { return date($style, $datetime); }}
好了,這個方法乾的活兒似乎多餘————這不是我們討論的重點,這隻是個例子。在其他類中使用這個 Trait:
Class FooBar{ use FormatDatetimeTrait; /** Other stuff **/ protected function getDate() { return $this->formatDatetime($this->time, $this->timeStyle); }}
我想這裡 Trait 的引用還是有好處的:
- 依賴關係明了,雖然和類的主業關係不大,但畢竟用到它了
- 匯入的方法可以改名(formatDatetime as formatTime)
- 客戶類可以在匯入函數基礎之上擴充
那麼,作為一種代碼重用的工具,這麼使用 Trait 都有那些缺點呢?是否違背 OOP 原則,或者違背它的設計初衷呢?
也歡迎有其他語言 Trait 使用經驗的朋友提出寶貴意見 :-)。
回複內容:
一般對於Util方法,不外乎下面幾種方法,以及我的一點看法:
- 依賴注入(好,但麻煩,且Util似乎與注入對象的主業關係不大)
- 弄一個包含Util方法的Container,然後注入(比上面那個只好一點點)
- 靜態方法(static is evil)
PHP 5.4 引入了 Trait,一般來說,用它作為 Interface 的預設實現似乎受眾比較多。
用 Trait 來匯入 Util 函數肯定是可行的,但這種解決方案是否違背 OOP 原則?是否最佳或者“優雅”呢?我舉個例子:
Trait FormatDatetimeTrait{ proteted function formatDatetime($datetime, $style) { return date($style, $datetime); }}
好了,這個方法乾的活兒似乎多餘————這不是我們討論的重點,這隻是個例子。在其他類中使用這個 Trait:
Class FooBar{ use FormatDatetimeTrait; /** Other stuff **/ protected function getDate() { return $this->formatDatetime($this->time, $this->timeStyle); }}
我想這裡 Trait 的引用還是有好處的:
- 依賴關係明了,雖然和類的主業關係不大,但畢竟用到它了
- 匯入的方法可以改名(formatDatetime as formatTime)
- 客戶類可以在匯入函數基礎之上擴充
那麼,作為一種代碼重用的工具,這麼使用 Trait 都有那些缺點呢?是否違背 OOP 原則,或者違背它的設計初衷呢?
也歡迎有其他語言 Trait 使用經驗的朋友提出寶貴意見 :-)。
Trait 屬於靜態模板(雖然可以被使用的類改寫),不具備繼承特性,所以不能用於繼承關係比較複雜的情境。比如:
有一個 BaseTrait,被兩個 UtilTraitA, UtilTraitB 都 use 了,然後呢,在一個類裡面,要同時用到這兩個 UtilTrait,這時問題來了,由於他們兩個都使用同一個BaseTrait,BaseTrait 裡面的方法就被重複匯入了,這種衝突直接報錯,並且無法解決。
Trait 的設計就是文法糖,具備類似繼承的特徵,但是和繼承不一樣。
所以,Util 方法全部改寫為 Trait 雖然一開始可行,但必定會遇到使用時的衝突,因為如果使用了 Util Trait,其他 User Trait 再使用 Util Trait,那麼使用這些 User Trait 的類極易產生匯入衝突。
那麼,Trait 應該怎麼用?當模版用!解決少量代碼重複的文法糖。絕對不可以把它用作繼承體系的一部分,並且要注意方法命名,盡量避免和其他類產生衝突。
最後,Trait 不可以 implement interface,PHP 這麼設計還是有道理的。
原討論: https://coding.net/u/fwolf/pp/25934
樓主,對於Trait的用途php官方文檔說的很詳細,你應該再仔細讀讀。
自 PHP 5.4.0 起,PHP 實現了代碼複用的一個方法,稱為 traits。
Traits 是一種為類似 PHP 的單繼承語言而準備的代碼複用機制。Trait 為了減少單繼承語言的限制,使開發人員能夠自由地在不同階層內獨立的類中複用方法集。Traits 和類組合的語義是定義了一種方式來減少複雜性,避免傳統多繼承和混入類(Mixin)相關的典型問題。
Trait 和一個類相似,但僅僅旨在用細粒度和一致的方式來組合功能。Trait 不能通過它自身來執行個體化。它為傳統繼承增加了水平特性的組合;也就是說,應用類的成員不需要繼承。
http://php.net/manual/zh/language.oop5.traits.php