[Modern PHP] 第二章 新特性之二 基於介面的編程

來源:互聯網
上載者:User
基於介面的編程

作為一個PHP程式員,學習如何基於介面進行編程改變了我的人生,大大提升了我通過整合第三方PHP組件來完善我的項目的能力。介面並不是新的功能,但是它卻是你日常工作中必須瞭解和使用的重要特性。

那麼PHP的介面到底是什嗎?介面是兩個PHP對象之間的契約,一個對象調用另一個對象時並不需要知道對方是什麼,而只需要知道對方能做什麼。介面可以降低我們代碼依賴關係的耦合性,允許我們的代碼調用任何實現了期望介面的第三方代碼。我們只需要關心第三方的代碼是否實現了介面就行,而根本不用關心第三方代碼是如何?這些介面的。我們來看一個現實中的例子。

假設我到佛羅里達的邁阿密參加Sunshine PHP開發人員大會。我想去城裡逛逛,所以我直接去了當地的汽車租賃公司。他們有一輛現代緊湊型的小車,一輛斯巴魯的旅行車和一輛布加迪威龍(太讓我驚訝了)。我知道我只是想藉助某個交通工具去城裡逛逛,這三輛車都可以滿足我的需求。但是每輛車又是那麼的與眾不同。現代雅紳特還不錯啦,但是我喜歡更有活力一點的。我沒有孩子,所以旅行車還是大了點。那麼,好吧就選布加迪好了。

現實是,我駕駛這三輛車中的任意一輛都可以,因為它們都共用了公用的、已知的介面。每輛車都有一個方向盤、一個油門踏板、一個刹車踏板和轉向燈,每輛車都使用汽油作為燃料。但是布加迪的動力強大到我都無法駕馭,但是現代車的駕駛介面卻和它一模一樣。因為三輛車都共用了同樣的已知的介面,但我有機會可以選擇我更喜歡的車型(實話實話,最終我可能還是會選擇現代)。

在PHP的物件導向方面也有同樣的概念。如果My Code中使用了某個特定的類(代表了特定的實現)的對象,那麼My Code的功能也固然變得非常有限,因為它只能永遠使用那個類的對象。然而,如果My Code將要用到的是一個介面,My Code立刻就能知道如何去使用任何實現了這個介面的對象。My Code根本不用關心介面是如何?的,My Code只關心對象是否實現了介面,讓我們用一個例子把這一切解釋清楚。

假設我們有一個PHP類名叫DocumentStore可以從不同的資料來源中擷取資料,它可以從一個遠端地址中擷取HTML,也可以從文檔流中讀取資料,還可以擷取終端的命令列輸出。每個儲存在DocumentStore執行個體中的文檔都有一個唯一的ID。例子 2-6 展示了DocumentStore類。

例子 2-6 DocumentStore類的定義

class DocumentStore{    protected $data = [];    public function addDocument(Documentable $document)    {        $key = $document->getId();        $value = $document->getContent();        $this->data[$key] = $value;    }    public function getDocuments()    {        return $this->data;    }}

如果addDocument方法只接收Documentable類的執行個體作為參數怎麼才能實現前面描述的功能?很好的觀察力。實際上Documentable不是一個類,而是一個介面,看看例子 2-7裡介面的定義

例子 2-7 Documentable介面的定義

interface Documentable{    public function getId();    public function getContent();}

在介面的定義中我們能看到任何實現了Documentable介面的對象都必須定義一個public的getId()方法和一個public的getContent()方法。

那麼這樣做的好處是什嗎?好處是我們可以分別構造多個功能迥異的文檔擷取類。例子 2-8展示了一個通過curl從遠程地址擷取HTML的介面實現。

例子 2-8 HtmlDocument類的定義

url = $url;    }    public function getId()    {        return $this->url;    }    public function getContent()    {        $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, $this->url);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);        curl_setopt($ch, CURLOPT_MAXREDIRS, 3);        $html = curl_exec($ch);        curl_close($ch);        return $html;    }}

另一個實現(例子 2-9)可以讀取給定資源中的資料流。

例子 2-9 StreamDocument類的定義

resource = $resource;        $this->buffer = $buffer;    }    public function getId()    {        return 'resource-' . (int)$this->resource;    }    public function getContent()    {        $streamContent = '';        rewind($this->resource);        while (feof($this->resource) === false) {            $streamContent .= fread($this->resource, $this->buffer);        }        return $streamContent;    }}

最後一個實現(例子 2-10)可以執行一個終端的命令並擷取執行結果

例子 2-10 CommandOutputDocument類的定義

command = $command;    }    public function getId()    {        return $this->command;    }    public function getContent()    {        return shell_exec($this->command);    }}

例子 2-11 展示了我們如何使用DocumentStore類來操作我們實現了Documentable介面的三個文檔收集類

例子 2-11 DocumentStore

addDocument($htmlDoc);// Add stream document$streamDoc = new StreamDocument(fopen('stream.txt', 'rb'));$documentStore->addDocument($streamDoc);// Add terminal command document$cmdDoc = new CommandOutputDocument('cat /etc/hosts');$documentStore->addDocument($cmdDoc);print_r($documentStore->getDocuments());

這樣做最大的亮點在於HtmlDocument、StreamDocument和CommandOutputDocument類除了介面一致外其它方面完全不同。

時至今日,對介面進行編程創造出了更靈活的代碼,我們不再關心具體的實現,而是將這些工作交給其他人來完成。越來越多的人(譬如你的同事,你的開源項目的使用者,或者你從來都沒有見過面的開發人員)可以寫出與你能夠彼此無縫對接的代碼,而他們僅僅只需要瞭解介面即可。

以上就介紹了[Modern PHP] 第二章 新特性之二 基於介面的編程,包括了方面的內容,希望對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.