首頁  >  文章  >  後端開發  >  PHP依賴倒置案例詳解

PHP依賴倒置案例詳解

php中世界最好的语言
php中世界最好的语言原創
2018-05-17 10:43:591732瀏覽

這次帶給大家PHP依賴倒置案例詳解,PHP依賴倒置的注意事項有哪些,以下就是實戰案例,一起來看一下。

什麼是依賴倒置呢?簡單地講就是將依賴關係倒置為依賴介面,具體概念如下:

1.上層模組不應該依賴下層模組,它們共同依賴一個抽象(父類別不能依賴子類,它們都要依賴抽象類別)

2.抽像不能依賴於具體,具體應該要依賴抽象。

注意,這裡的介面不是狹義的介面

為什麼要依賴介面?因為介面體現對問題的抽象,同時由於抽像一般是相對穩定的或是相對變化不頻繁的,而具體是易變的。因此依賴抽像是實作程式碼擴充和運行期內綁定(多態)的基礎:只要實作了該抽象類別的子類,都可以被類別的使用都使用。這裡,強調一下擴展性這個概念。通常擴展性指對已知行為的擴展,在講述介面時,也提到過,介面應該是相對的。這就告訴我們,無論使用多麼先進的設計模式,也無法做到不需要修改程式碼即可達到不變應萬變的地上。在物件導向的這五大原則裡,我認為依賴倒置是最難理解,也是最難實現的。

這裡以僱員類別為例

<?php
interface employee
{
  public function working();
}
class teacher implements employee
{
  public function working()
  {
    echo &#39;teaching...&#39;;
  }
}
class coder implements employee
{
  public function working()
  {
    echo &#39;coding...&#39;;
  }
}
class workA
{
  public function work()
  {
    $teacher = new teacher();
    $teacher->working();
  }
}
class workB
{
  private $e;
  public function set(employee $e)
  {
    $this->e = $e;
  }
  public function work()
  {
    $this->e->working();
  }
}
$worka = new workA;
$worka->work();
$workb = new workB;
$workb->set(new teacher());
$workb->work();

在workA中,work方法依賴teacher實作;在workB中,work轉而依賴抽象,這樣可以把需要的物件經由參數傳入。上述程式碼透過接口,實現了一定程度的解耦,但仍然是有限的。不僅是使用接口,使用工廠等也能實現一定程度的解耦和依賴倒置。

在workB中,teacher實例透過set方法傳入,從而實現了工廠模式。由於這樣的實作仍然是硬編碼的,為了實現程式碼的進一步擴展,把這個依賴關係寫在設定檔裡,指明workB需要一個teacher對象,專門由一個程式配置是否正確(如所依賴的類別檔案是否存在)以及載入配置中所依賴的實現,這個檢測程序,就稱為IOC容器。

很多文章看到IOC(Inversion of Control)概念,實際上,IOC是依賴倒置原則(Dependence Inversion Principle,DIP)的同義詞。而在提IOC的時候,你可能還會看到有人提起DI等概念。 DI,即依賴注入,一般認為,依賴注入(DI)和依賴查找(DS)是IOC的兩種實作。不過隨著某些概論的演化,這幾個概念之間的關係也變得很模糊,也有人認為IOC就是DI。有人認為,依賴注入的描述比起IOC來更貼切,這裡不糾纏於這幾個概念之間的關係。

在經典的J2EE設計裡,通常把DAO層和Servicen層細分為介面層和實作層,然後在設定檔裡進行所依賴關係的配置,這是最常見的DIP的應用。 Spring框架就是一個很好的IOC容器,把控制權從程式碼剝離到IOC窗口,這裡是透過XML設定檔實現的,Spring在執行期間根據設定檔的設定,建立物件之間的依賴關係。

如下面的程式碼所示

<bean scopre="prototype" class="cn.notebook.action.NotebookListOtherAction" id="notebookListOtherAction">
  <property ref="userReplyService" name="userReplyService" />
  <property ref="userService" name="userService" />
  <property ref="permissionService" name="permissionService" />
  <property ref="friendService" name="friendService" />
</bean>

但是這樣的設定一樣存在問題,設定檔會變得越來越大,其間關係會越來越複雜。同樣逃脫不了隨著應用程式和業務的改變,不斷修改程式碼的惡魘(這裡認為設定檔是程式碼的一部分。並且在實際開發中,很少存在單純修改設定檔的情況。一般設定檔修改了,程式碼也會做相應的修改)

在PHP裡,也有類似模仿Spring的實現,也就是把依賴關係寫在了設定檔裡,透過設定檔來產生需要的物件。我覺得這樣的程式碼還是為了實現而實現。在Srping裡,設定檔裡配置的不僅是一個類別執行時期的依賴關係,還可以實現事務管理、AOP、延遲載入等。而PHP要實現上面的種種特性,其消耗是巨大的。從語言層面講,PHP這種動態腳本語言在實作一些多型特性上和編譯型的語言不同。其次PHP作為敏捷性的開發語言,更強調快速開發、邏輯清晰、程式碼更簡單易懂,如果再附加了各種設計模式的框架,從技術實作和運作效率來看,都是不可取的。依賴倒置的核心原則是解耦。如果脫離這個最原始的原則,那就是本末倒置。

事實上,很多的設計模式裡已經隱含了依賴倒置原則我們也在有意無意地做著一些依賴反轉的工作。只是作為PHP,目前還沒有一個比較完善的IOC容器,或許是PHP根本不需要。

如果滿足DIP:

1.每個較高層次類別都為它所需要的服務提出一個介面聲明,較低層次類別實作實作這個介面。

2.每個高層次類別都透過該抽象介面使用服務。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

Bootstrap PHP實作多圖上傳步驟詳解

CI框架實作購物車功能步驟詳解

以上是PHP依賴倒置案例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn