中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Laravel面向接口編程的實現

發布時間:2021-01-25 12:26:36 來源:億速云 閱讀:259 作者:小新 欄目:編程語言

這篇文章主要介紹了Laravel面向接口編程的實現,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

面向接口編程是編碼中的一種設計思想,這種方式基于接口而不是固定的類來構建應用程序。

如果您是一名程序員,那么您可能聽說過則這樣的說法,例如:面向接口編程、使用抽象類代替固定類等等。

這些都是說的同一件事,編寫應用程序代碼時,使其依賴抽象接口而不是具體的類。

為什么?

這是我第一次聽到這句話時的確切反應。為什么要使用接口而不是類?即使創建了接口,我也需要創建一個實現該接口的類。這不是浪費時間嗎?

當然不是!!

這個世界上唯一不變的就是變化本身,也就是說,變化是永恒的。

就編程而言,這同樣沒有例外。業務需求隨著時間變化,我們的代碼也要隨之變化。

所以代碼必需保持靈活。

面向接口編程可以使代碼松散耦合且靈活。

怎么做?

觀察下面的代碼。

class Logger {
    public function log($content) 
    {
        //日志保存到文件中.
        echo "Log to file";
    }
}

這是一個將日志記錄到文件的簡單類。 我們可以在控制器中調用它。

class LogController extends Controller
{
    public function log()
    {
        $logger = new Logger;
        $logger->log('Log this');
    }
}

但如果需要將日志記錄到多個地方 (如數據庫,文件,云端等) 時,我們又該怎么辦呢。

然后我們可以更改 LogController 和 Logger 類以適應這些更改。

class Logger {
    public function logToDb($content) 
    {
        //將日志記錄到 db.
    }
    public function logToFile($content) 
    {
        //將日志保存到 file.
    }
    public function logToCloud($content) 
    {
        //將日志存儲到 cloud.
    }
}
class LogController extends Controller
{
    public function log()
    {
        $logger = new Logger;
        $target = config('log.target');
        if ($target == 'db') {
            $logger->logToDb($content);
        } elseif ($target == 'file') {
            $logger->logToFile($content);
        } else {
            $logger->logToCloud($content);
        }
    }
}

現在我們可以記錄不同的目標了。但是,如果我們想將其他目標 (例如日志) 添加到 redis 服務器,該怎么辦?最后,我們將同時修改 Logger 類和 LogController 類。

如您所見,這很快就擺脫了我們的控制,并且代碼變得混亂。Logger 類很快成為一個整體。這是一場噩夢。

因此,我們需要拆分事物。遵循 SOLID 原則,我們可以將職責移至相應的類。

class DBLogger
{
    public function log()
    {
        //將日志記錄到 db
    }
}
class FileLogger
{
    public function log()
    {
        //將日志保存到 file
    }
}
class CloudLogger
{
    public function log()
    {
        //將日志存儲到 cloud
    }
}

并且控制器更改為:

class LogController extends Controller
{
    public function log()
    {
        $target = config('log.target');
        if ($target == 'db') {
            (new DBLogger)->log($content);
        } elseif ($target == 'file') {
            (new FileLogger)->log($content);
        } else {
            (new CloudLogger)->log($content);
        }
    }
}

這樣就好多了。現在如果要添加其他日志記錄目標,我們可以創建一個新類并將其添加到 Controller 中的 if-else。

但是,我們的控制器仍然負責選擇記錄器。對于控制器,不需要知道不同的記錄器并在它們之間進行選擇。它只需要一個帶有 log() 方法的記錄器類來記錄內容。

使用接口

這種情況就適合使用接口。那么什么是接口?

接口是對對象可以執行的操作的描述。

以我們的示例為例,控制器僅需要帶有 log() 方法的記錄器類。因此,我們的接口必須描述它必須具有 log() 方法。

interface Logger
{
    public function log($content);
}

如您所見,它僅包含函數聲明,而不包含其實現,這就是為什么將其稱為抽象的原因。

實現接口時,實現接口的類必須提供接口中定義的抽象方法的實現細節。

在我們的示例中,任何實現 Logger 接口的類都必須提供抽象方法 log () 的實現細節。

然后,我們可以在控制器中注入此接口。

class LogController extends Controller
{
    public function log(Logger $logger)
    {
        $logger->log($content);
    }
}

現在,控制器不再關心傳遞給它的記錄器類型。它需要知道的是它必須實現 Logger 接口。

因此,我們需要修改 Logger 類以實現此接口。

class DBLogger implements Logger
{
    public function log()
    {
        //將日志記錄到 db
    }
}
class FileLogger implements Logger
{
    public function log()
    {
        //將日志存儲到 file
    }
}
class CloudLogger implements Logger
{
    public function log()
    {
        //將日志保存到 cloud
    }
}

現在,我們可以添加更多記錄器,而無需觸及現有代碼。我們要做的就是創建一個實現 Logger 接口的新類。

class RedisLogger implements Logger
{
    public function log()
    {
        //將日志存儲到 redis
    }
}

我們的代碼現在看起來就變得靈活,低耦合了,我們可以隨時改變實現方式而不用去改動之前的代碼。

依賴注入

當我們使用的是 Laravel 框架,我們可以使用服務容器去自動注冊接口的實現。

因為 Laravel 提供開箱即用的方法注入,所以我們只需要把接口和實現綁定起來。

首先我們需要創建一個 logger 的配置文件。 就像這樣

<?php
return [
    'default' => env('LOG_TARGET', 'file'),
    'file' => [
        'class' => App\Log\FileLogger::class,
    ],
    'db' => [
        'class' => App\Log\DBLogger::class,
    ],
    'redis' => [
        'class' => App\Log\RedisLogger::class,
    ]
];

然后在 app/Providers 路徑下 AppServiceProvider.php 的文件添加如下代碼

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $default = config('log.default');
        $logger = config("log.{$default}.class");
        $this->app->bind(
            App\Contracts\Logger::class, // the logger interface
            $logger
        );
    }
}

這樣做的效果是,從 logger.php 配置文件讀取默認的 logger ,然后綁定到 Logger interface 。這樣當我們使用 Logger interface ,容器將會幫我們解析并返回默認的 Logger 實例。

因為默認的 logger 是使用 env() 助手指定的,所以我們可以在不同的環境使用不同的 logger ,例如本地環境使用 file ,生產環境使用 db 。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Laravel面向接口編程的實現”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荥经县| 竹溪县| 宽甸| 雷山县| 皮山县| 家居| 仲巴县| 四子王旗| 贵港市| 西华县| 云林县| 崇左市| 武冈市| 商洛市| 安龙县| 巴彦县| 来凤县| 碌曲县| 军事| 开远市| 儋州市| 酒泉市| 新宾| 于田县| 额济纳旗| 汉川市| 夏津县| 全椒县| 务川| 绥阳县| 扎鲁特旗| 彭水| 礼泉县| 黔东| 舞阳县| 勃利县| 玛多县| 莒南县| 民乐县| 通城县| 彭山县|