1. 程式人生 > >面向物件的五大設計原則之依賴倒置原則

面向物件的五大設計原則之依賴倒置原則

依賴倒置原則(depend ence inversion principle,簡稱DIP),簡單來說就是將依賴關係倒置為依賴介面,具體就是,上層模組不應該依賴於下層模組,它們共同依賴於一個抽象(父類不能依賴子類,應該共同依賴於抽象類)。抽象不能依賴於具體,但是具體應該依賴於抽象,我們要注意下,咱們這裡的介面並不是指狹義上的介面。

因為介面體現了對問題的抽象,同時又因為抽象一般是相對穩定的,或者說相對變化不是太頻繁,而具體是很容易就會產生變化的,所以我們依賴抽象是實現程式碼擴充套件和執行期內繫結(多型)的基礎,只要實現了該抽象的子類,就都可以被類的使用者所使用。

咱們再來看下這個擴充套件性的概念啊,這個擴充套件性啊,通常是指對已知行為的擴充套件,並且咱們知道,介面是相對穩定的,所以,我們無論是用多麼先進的設計模式,也不可能做到不需要修改程式碼就達到以不變應萬變的地步,所以嘞,這個依賴倒置原則,我認為是最難理解和實現的。

先來看一個程式碼段:

interface employee
{
    public function working();
}

class teacher implements employee
{
    public function working()
    {
        // TODO: Implement working() method.
        echo "teacher";
    }
}

class coder implements employee
{
    public function working()
    {
        // TODO: Implement working() method.
        echo "coder";
    }
}

class w_1
{
    public function work()
    {
        $teacher = new teacher();
        $teacher->working();
    }
}

class w_2
{
    private $a;

    public function set(employee $a)
    {
        $this->a = $a;
    }

    public function work()
    {
        $this->a->working();
    }
}

$w_1 = new w_1();
$w_1->work();
$w_2 = new w_2();
$w_2->set(new teacher());
$w_2->work();

咱們來梳理下上述程式碼,首先上述程式碼的w_1類的work方法,它的實現是依賴於teacher,但是w_2呢,是依賴於抽象來實現的,這樣一來,我們就可以把需要的物件通過引數傳入,就可以獲取了,上述程式碼呢,通過介面,實現了一定程度上的解耦,但仍然是有限的,我們不僅僅是使用介面,使用工廠模式也是可以簡單來實現一定程度的解耦和依賴倒置的。

在w_2類中,teacher例項通過set方法傳入,實現了工廠模式,這樣的方式是屬於硬編碼的,為了實現程式碼的進一步擴充套件,我們會把這個依賴關係寫在配置檔案裡,指明瞭w_2類需要一個teacher例項物件,並且專門有一個程式來檢測配置是否正確(如所以來的類檔案是否存在等)以及載入配置中所依賴的實現,這個檢測程式,我們可以稱為IOC容器(inversion of control)。

IOC是依賴倒置原則的同義詞,偶爾還會關聯到DI、DS等概念,DI就是指依賴注入,DS就是指依賴查詢,一般認為這兩個東西是IOC的兩種實現,不過,隨著某些概念的演化,這幾個概念之間的關係也變得很模糊,也有人認為IOC就是依賴注入,因為他們認為依賴注入的描述比IOC更加的貼切,咱們在這裡就不討論這個了啊。

事實上,很多設計模式裡已經隱含了依賴倒置原則,我們也在有意無意的進行著一些依賴倒置的工作,這個依賴倒置它的核心是解耦,脫離了這個,一切都是本末倒置,並且在PHP裡,目前來說還沒有一個較為完善的IOC容器,並且如果是通過PHP來實現IOC容器等功能的話,倒不是不可以,只是從技術實現和執行效率方面來看的話,都是不符合我們使用PHP來進行開發的初衷的,咱們在這裡呢,不對這個原則的好壞進行判斷,只是簡單介紹下這個原則。

滿足依賴倒置原則有兩個方面:

  1. 每個較高層次的類都為它所需要的服務提出一個介面宣告,較低層次的類實現這個介面
  2. 每個高層類都通過該抽象介面使用服務

好啦,本次記錄就到這裡了。

如果感覺不錯的話,請多多點贊支援哦。。。