成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel中的核心概念

ddongjian0000 / 1499人閱讀

摘要:可以為服務(wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊(cè)之后調(diào)用。所有服務(wù)提供者都在配置文件中注冊(cè)。可以選擇推遲服務(wù)提供者的注冊(cè),直到真正需要注冊(cè)綁定時(shí),這樣可以提供應(yīng)用程序的性能。

本文最早發(fā)布于 Rootrl的Blog

導(dǎo)言

Laravel是一款先進(jìn)的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認(rèn)為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP OOP知識(shí)。我相信很多人對(duì)比如getter setter以及__invoke、__call、__callStatic這些魔術(shù)方法甚至this、
self、static這些關(guān)鍵字作用都還是很模糊的(我上一個(gè)老大喜歡問這種基礎(chǔ)問題,然后答不上來-_-")。

DI & IoC

首先名詞解釋,DI全稱是Dependency injection,依賴注入的意思。而IoC是Inversion of control 控制反轉(zhuǎn)。

要了解依賴注入和控制反轉(zhuǎn),首先我們不得不提到面向?qū)ο笤O(shè)計(jì)中的五大設(shè)計(jì)原則:S.O.L.I.D。

S.O.L.I.D - 面向?qū)ο笪宕笤O(shè)計(jì)原則

SRP The Single Responsibility Principle 單一責(zé)任原則
OCP The Open Closed Principle 開放封閉原則
LSP The Liskov Substitution Principle 里氏替換原則
ISP The Interface Segregation Principle 接口分離原則
DIP The Dependency Inversion Principle 依賴倒置原則

這五種思想原則對(duì)我們平常的軟件開發(fā)設(shè)計(jì)非常重要,大家可以具體去了解下。

依賴倒置原則

這里我們重點(diǎn)講下依賴倒置原則:實(shí)體必須依靠抽象而不是具體實(shí)現(xiàn)。它表示高層次的模塊不應(yīng)該依賴于低層次的模塊,它們都應(yīng)該依賴于抽象。

在傳統(tǒng)軟件設(shè)計(jì)中,我們一般都是上層代碼依賴下層代碼,當(dāng)下層代碼變動(dòng)時(shí),我們上層代碼要跟著變動(dòng),維護(hù)成本比較高。這時(shí)我們可以上層定義接口,下層來實(shí)現(xiàn)這個(gè)接口,從而使得下層依賴于上層,降低耦合度。(PC主板和鼠標(biāo)鍵盤接口就是一個(gè)很好的例子,各數(shù)據(jù)廠商根據(jù)主板上的接口來生產(chǎn)自己的鼠標(biāo)鍵盤產(chǎn)品,這樣鼠標(biāo)壞了后我們可以隨便換個(gè)符合接口要求的鼠標(biāo),而不用修改主板上的什么東西)

控制反轉(zhuǎn)

上面講的依賴倒置是一種原則,而控制反轉(zhuǎn)就是實(shí)現(xiàn)依賴倒置的一種具體方法??刂品崔D(zhuǎn)核心是把上層(類)所依賴單元的實(shí)例化過程交由第三方實(shí)現(xiàn),而類中不允許存在對(duì)所依賴單元的實(shí)例化語句。舉個(gè)例子:

class Comment
{
    ...

    public function afterInsert()
    {
        $notification = new EmailNotification(...);
        $notification->send(...);
    }
}

如上,假如我們?cè)谟脩籼峤辉u(píng)論后通知被評(píng)論者,這里通知方式是郵件,而且是直接在類中實(shí)例化郵件通知類,這樣代碼耦合度高,如果換個(gè)短信通知方式就不得不改這里面代碼,具體好的實(shí)現(xiàn)我們下面會(huì)講到。

依賴注入

依賴注入是一種設(shè)計(jì)模式,是一種IoC的具體實(shí)現(xiàn),實(shí)現(xiàn)了IoC自然就符合依賴倒置原則。依賴注入的核心思想是把類中所依賴單元的實(shí)例化過程放到類外面中去實(shí)現(xiàn),然后把依賴注入進(jìn)來。常用的依賴注入方式有屬性注入和構(gòu)造函數(shù)注入。比如用構(gòu)造函數(shù)注入解耦上面代碼:

// 通知接口
interface Notifaction
{
    public function send(...);
}


// 短信通知實(shí)現(xiàn)通知接口
class SmsNotification implements Notification
{
    public function send(...)
    {
        ...
    }
}

// 評(píng)論類
class Comment
{
    ...

    protected $notification;

    public function __construct(Notification $smsNotification)
    {
        $this->notification = $smsNotification;
    }

    public function afterInsert()
    {
        $this->notification->send(...);
    }
}

// 實(shí)例化短信通知類
$smsNotification = new SmsNotification(...);

// 通過構(gòu)造函數(shù)方法注入
$comment = new Comment($smsNotification);

...

$comment->save();

這樣,我們先定義Notification接口,里面有個(gè)send方法,讓后面的通知者不管是郵件類還是短信類都實(shí)現(xiàn)這個(gè)接口,然后在外面通過構(gòu)造函數(shù)方式注入進(jìn)來,這樣就解決了Comment類對(duì)具體通知方法的依賴,只要是實(shí)現(xiàn)了Notification接口的,都可以通過構(gòu)造函數(shù)傳進(jìn)來,Comment類完全不用做任何修改。這樣無論對(duì)于代碼維護(hù)還是單元測(cè)試(可以模擬實(shí)現(xiàn)一個(gè)Notification類),都非常方便。

依賴注入是IoC的一種具體實(shí)現(xiàn),是一種解耦手段。當(dāng)然IoC不止這一種實(shí)現(xiàn),比如Yii中的Service Locator(服務(wù)定位器)

IoC container/DI container

當(dāng)項(xiàng)目比較大時(shí),就會(huì)有許多類似上面評(píng)論類和通知類這種依賴關(guān)系,整個(gè)項(xiàng)目會(huì)非常復(fù)雜。這時(shí)候就需要一個(gè)集中的地方來管理這些依賴,我們把它叫IoC container 控制反轉(zhuǎn)容器,它提供了動(dòng)態(tài)地創(chuàng)建、注入依賴單元、映射依賴關(guān)系等功能。這樣可以集中管理依賴關(guān)系,也減少很多代碼量。

Service container 服務(wù)容器

Laravel官方文檔這樣定義服務(wù)容器:Laravel服務(wù)容器是用于管理類的依賴和執(zhí)行依賴注入的工具。

首先,服務(wù)容器通過DI依賴注入方式實(shí)現(xiàn)了IoC,然后它還支持另一種實(shí)現(xiàn):綁定與解析。

綁定

幾乎所有服務(wù)容器綁定操作都是Service provider(服務(wù)提供器)中注冊(cè)綁定的,服務(wù)提供器中可以通過$this->app方式獲取服務(wù)容器,然后通過服務(wù)容器提供的方法比如$this->app->bind(...)等進(jìn)行具體服務(wù)綁定。類似支持的綁定方式還有:

簡(jiǎn)單綁定

綁定單例

綁定實(shí)例

綁定初始數(shù)據(jù)

綁定接口到實(shí)現(xiàn)

上下文綁定

標(biāo)記

擴(kuò)展綁定

具體可以查看官方文檔:https://laravel.com/docs/5.6/...

解析

綁定后可以從服務(wù)容器中解析出對(duì)象才能夠使用。解析方法包括:

通過 make 方法,接收一個(gè)你想要解析的類或者接口

通過數(shù)組方式從容器中解析對(duì)象

自動(dòng)注入

示例

我們先定義一個(gè)自己的類

class Foo
{
    public function bar()
    {
        ...
    }
}

我們把Foo類簡(jiǎn)單綁定到服務(wù)容器:

App::bind("foo", function($app){
    return new Foo();
})

平時(shí)在上下文獲取這個(gè)實(shí)例:

$foo = App::make("foo");    // $foo就是Foo類的實(shí)例

當(dāng)然,這種綁定和解析平時(shí)我們?cè)诖a中隨便可以寫到哪里,但是多了的話就亂起來了。所以我開頭說幾乎所有這種依賴服務(wù)綁定操作都是在Service provider中進(jìn)行的。

下面就給大家介紹Service provider。

Service provider 服務(wù)提供器

為了讓依賴注入的代碼不至于混亂,Laravel提供了一個(gè)服務(wù)提供器(Service Provider),它將這些依賴聚集在了一塊,統(tǒng)一申明和管理,讓依賴變得更加容易維護(hù)。

下面都是一些抄來的官話、套話(-_-"),大家可以直接跳到代碼示例,后續(xù)再查看官方文檔加深理解。

所有服務(wù)提供者都需要繼承IlluminateSupportServiceProvider類。大多數(shù)服務(wù)提供者都包含 register 和 boot 方法。register方法中,只能將事務(wù)綁定到服務(wù)容器。不應(yīng)該在register方法中嘗試注冊(cè)任何事件監(jiān)聽器,路由或者任何其他功能。可以為服務(wù)提供者的boot方法設(shè)置類型提示。服務(wù)容器會(huì)自動(dòng)注入需要的任何依賴。boot方法將在所有其他服務(wù)提供者均已注冊(cè)之后調(diào)用。

所有服務(wù)提供者都在 config/app.php 配置文件中注冊(cè)。可以選擇推遲服務(wù)提供者的注冊(cè),直到真正需要注冊(cè)綁定時(shí),這樣可以提供應(yīng)用程序的性能。

示例

上一個(gè)示例我們是自己在上下文中隨意定義、獲取。下面我們以服務(wù)提供者的方式進(jìn)行:

use IlluminateSupportServiceProvider;

class FooServiceProvider extends ServiceProvider {

    public function register()
    {
        $this->app->bind("foo", function()
        {
            return new Foo();
        });
    }

}

上面實(shí)現(xiàn)了一個(gè)Foo的服務(wù)提供,我們可以手動(dòng)注入到上下文中:

App::register("FooServiceProvider");

當(dāng)然我們更多的是通過配置文件來完成的,在app/config/app.php中的providers數(shù)組里面增加一行:

"providers" => [
    …
       ‘FooServiceProvider’,
],

這樣我們可以在上下文中直接獲取實(shí)例:

App::make(‘foo’)

當(dāng)然,我們還可以通過門面方式,更方便的操作Foo類。

Facades 門面

門面實(shí)際上是應(yīng)用了設(shè)計(jì)模式中的外觀模式:

外觀模式(Facade),他隱藏了系統(tǒng)的復(fù)雜性,并向客戶端提供了一個(gè)可以訪問系統(tǒng)的接口。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)性模式。為子系統(tǒng)中的一組接口提供了一個(gè)統(tǒng)一的訪問接口,這個(gè)接口使得子系統(tǒng)更容易被訪問或者使用。

Laravel中隨處可見這些靜態(tài)方法的調(diào)用:

$value = Cache::get("key");

這些靜態(tài)調(diào)用實(shí)際上調(diào)用的并不是靜態(tài)方法,而是通過PHP的魔術(shù)方法 __callStatic() 將請(qǐng)求轉(zhuǎn)到了相應(yīng)的方法上。

比如如果我們看一下 IlluminateSupportFacadesCache 這個(gè)類,你會(huì)發(fā)現(xiàn)類中根本沒有 get 這個(gè)靜態(tài)方法:

class Cache extends Facade
{
    /**
     * 獲取組件的注冊(cè)名稱。
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return "cache"; }
}

這其中的奧秘在基類Facade中:

public static function __callStatic($method, $args)
{
    // 獲取實(shí)例
    $instance = static::getFacadeRoot();

    if (!$instance) {
        throw new RuntimeException("A facade root has not been set.");
    }

    // 真正調(diào)取對(duì)應(yīng)的方法
    return $instance->$method(...$args);
}

這里面有一個(gè)獲取實(shí)例的過程,然后去調(diào)用具體方法。

示例

接上一個(gè)示例,我們平常是通過App::make("foo")來獲取實(shí)例,然后再調(diào)用具體方法。現(xiàn)在我們通過門面的方式簡(jiǎn)化這個(gè)流程:

先定義一個(gè)門面:

use IlluminateSupportFacadesFacade;

class Foo extends Facade {

    protected static function getFacadeAccessor() { return ‘foo’; }

}

然后我們可以很方便的使用Foo類某個(gè)方法:

Foo::bar();
Contracts 契約

Laravel的契約是一組定義框架提供的核心服務(wù)的接口。后續(xù)針對(duì)這個(gè)接口可以有多種實(shí)現(xiàn),解耦了具體實(shí)現(xiàn)的依賴,在不改變代碼邏輯的情況下獲得更加多態(tài)的結(jié)果。

比如你只需在配置文件中指明你需要的緩存驅(qū)動(dòng)(redis,memcached,file等),Laravel會(huì)自動(dòng)幫你切換到這種驅(qū)動(dòng),而不需要你針對(duì)某種驅(qū)動(dòng)更改邏輯和代碼。

總結(jié)

這些都是些基礎(chǔ)的抽象概念,但是是非常重要的,Laravel中隨處可見這些思想,是一切實(shí)現(xiàn)的基石。

學(xué)習(xí)的過程中基礎(chǔ)是非常重要的,知其然必知其所以然。就像道與術(shù),道是在術(shù)之前的,老子說過:”有道無術(shù),術(shù)尚可求也,有術(shù)無道,止于術(shù)“。不過實(shí)際中應(yīng)該是相輔相成的關(guān)系,“以道統(tǒng)術(shù),以術(shù)得道”。

引用

https://laravel.com/docs/5.6/...
https://laravel-china.org/doc...
http://www.digpage.com/di.html
http://yansu.org/2014/12/06/i...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28823.html

相關(guān)文章

  • Laravel思維導(dǎo)圖之Laravel核心概念

    摘要:的核心概念包括服務(wù)容器服務(wù)提供者門面契約。所有服務(wù)提供者都需要繼承類。可以為服務(wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊(cè)之后調(diào)用。同樣會(huì)整理成思維導(dǎo)圖的形式以方便記憶與回顧。 showImg(https://segmentfault.com/img/remote/1460000010771201); Laravel 的核心概念包括:服務(wù)容器、服務(wù)提供者、門面(Fac...

    wthee 評(píng)論0 收藏0
  • 深入剖析 Laravel 服務(wù)容器

    摘要:劃下重點(diǎn),服務(wù)容器是用于管理類的依賴和執(zhí)行依賴注入的工具。類的實(shí)例化及其依賴的注入,完全由服務(wù)容器自動(dòng)的去完成。 本文首發(fā)于 深入剖析 Laravel 服務(wù)容器,轉(zhuǎn)載請(qǐng)注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請(qǐng)求,又是如何生成響應(yīng)并最終呈現(xiàn)給用戶的工作原理。 本章將帶領(lǐng)大...

    abson 評(píng)論0 收藏0
  • Laravel 深入核心系列教程

    摘要:前言年底了不太忙,最近一段時(shí)間也一直在研究,就想寫篇關(guān)于比較深一點(diǎn)的教程系列啥的,于是就找到站長(zhǎng)給開了寫教程的渠道。優(yōu)點(diǎn)的就是為藝術(shù)家創(chuàng)造的框架,它也是工程化的趨勢(shì)。項(xiàng)目維護(hù)方便也是事實(shí)。如果有遇到問題可以直接在教程下面留言。 前言 年底了不太忙,最近一段時(shí)間也一直在研究laravel,就想寫篇關(guān)于laravel比較深一點(diǎn)的教程系列啥的,于是就找到站長(zhǎng)給開了寫教程的渠道。由于第一次寫,...

    wemall 評(píng)論0 收藏0
  • Laravel 5.4 入門系列 13. 終篇: 小白也能看懂的 Laravel 核心概念講解

    摘要:但是服務(wù)通常由服務(wù)提供者來管理的。小結(jié)通過上述的例子,基本上可以理解服務(wù)容器和服務(wù)提供者的使用。懂得了服務(wù)容器和服務(wù)提供者,理解門面也就不難了。 自動(dòng)依賴注入 什么是依賴注入,用大白話將通過類型提示的方式向函數(shù)傳遞參數(shù)。 實(shí)例 1 首先,定義一個(gè)類: /routes/web.php class Bar {} 假如我們?cè)谄渌胤揭褂玫?Bar 提供的功能(服務(wù)),怎么辦,直接傳入?yún)?shù)即...

    BenCHou 評(píng)論0 收藏0
  • PHP相關(guān)

    摘要:的機(jī)器學(xué)習(xí)庫(kù)的機(jī)器學(xué)習(xí)庫(kù),包括算法交叉驗(yàn)證神經(jīng)網(wǎng)絡(luò)等內(nèi)容。在即將到來的大會(huì)上,她將和大家分享在機(jī)器學(xué)習(xí)領(lǐng)域的全新可能。入門總結(jié)入門相關(guān),如安裝配置基本使用等。 基于 Swoole 開發(fā) PHP 擴(kuò)展 Swoole-1.9.7 增加了一個(gè)新特性,可以基于 Swoole 使用 C++ 語言開發(fā)擴(kuò)展模塊,在擴(kuò)展模塊中可以注冊(cè) PHP 內(nèi)置函數(shù)和類?,F(xiàn)在可以基于 Swoole 來編寫 PHP ...

    lewinlee 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<