首頁 後端開發 php教程 [Modern PHP] 第二章 新特性之二 基於介面的編程

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

Jul 30, 2016 pm 01:31 PM
function public this

基於介面的程式設計

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

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

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

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

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

假設我們有一個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類別的定義

<?php
class HtmlDocument implements Documentable
{
    protected $url;

    public function __construct($url)
    {
        $this->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類別的定義

<?php
class StreamDocument implements Documentable
{
    protected $resource;
    protected $buffer;

    public function __construct($resource, $buffer = 4096)
    {
        $this->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 CommandDDocument類的定義範例2-11 展示了我們如何使用DocumentStore類別來操作我們實作了Documentable介面的三個文件收集類別


範例2-11 DocumentStore

<?php
class CommandOutputDocument implements Documentable
{
    protected $command;

    public function __construct($command)
    {
        $this->command = $command;
    }

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

    public function getContent()
    {
        return shell_exec($this->command);
    }
}
登入後複製
DocuDocucumentStore除了接口一致外其它方面完全不同。
時至今日,對介面進行程式設計創造出了更靈活的程式碼,我們不再關心具體的實現,而是將這些工作交給其他人來完成。越來越多的人(譬如你的同事,你的開源專案的用戶,或者你從來沒有見過面的開發者)可以寫出與你能夠彼此無縫對接的程式碼,而他們僅僅只需要了解接口即可。

以上就介紹了[Modern PHP] 第二章 新特性之二 基於介面的編程,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

function是什麼意思 function是什麼意思 Aug 04, 2023 am 10:33 AM

function是什麼意思

iOS的developer版和public版有什麼不同? iOS的developer版和public版有什麼不同? Mar 01, 2024 pm 12:55 PM

iOS的developer版和public版有什麼不同?

MySQL.proc表的作用與功能詳解 MySQL.proc表的作用與功能詳解 Mar 16, 2024 am 09:03 AM

MySQL.proc表的作用與功能詳解

'enumerate()'函數在Python中的用途是什麼? 'enumerate()'函數在Python中的用途是什麼? Sep 01, 2023 am 11:29 AM

'enumerate()'函數在Python中的用途是什麼?

Vue.use函數的用法與作用 Vue.use函數的用法與作用 Jul 24, 2023 pm 06:09 PM

Vue.use函數的用法與作用

在PHP中的file_exists()函數 在PHP中的file_exists()函數 Sep 14, 2023 am 08:29 AM

在PHP中的file_exists()函數

js函數function用法是什麼 js函數function用法是什麼 Oct 07, 2023 am 11:25 AM

js函數function用法是什麼

如何在PHP中使用SOA函數 如何在PHP中使用SOA函數 May 18, 2023 pm 01:10 PM

如何在PHP中使用SOA函數

See all articles