用Trait來匯入Util函數能否作為一種解決方案?

來源:互聯網
上載者:User
一般對於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

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.