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

資訊專欄INFORMATION COLUMN

Laravel與Repository Pattern(倉(cāng)庫(kù)模式)——概念篇

tomener / 1917人閱讀

摘要:確實(shí),要獨(dú)立一個(gè)操作層出來(lái),確實(shí)會(huì)增加大量代碼,非常繁瑣。如果你是小項(xiàng)目,未必需要使用這一模式。但如果是年以上的復(fù)雜大型項(xiàng)目,這種模式的好處就比較明顯了。如果你是純新手,建議你暫時(shí)不要往下看,先把用得比較熟練后再回來(lái)學(xué)習(xí)。

為什么要學(xué)習(xí)Repository Pattern(倉(cāng)庫(kù)模式)

Repository 模式主要思想是建立一個(gè)數(shù)據(jù)操作代理層,把controller里的數(shù)據(jù)操作剝離出來(lái),這樣做有幾個(gè)好處:

把數(shù)據(jù)處理邏輯分離使得代碼更容易維護(hù)

數(shù)據(jù)處理邏輯和業(yè)務(wù)邏輯分離,可以對(duì)這兩個(gè)代碼分別進(jìn)行測(cè)試

減少代碼重復(fù)

降低代碼出錯(cuò)的幾率

讓controller代碼的可讀性大大提高

然而,據(jù)很多同學(xué)反應(yīng),這一部分很難學(xué)。確實(shí),要獨(dú)立一個(gè)操作層出來(lái),確實(shí)會(huì)增加大量代碼,非常繁瑣。如果你是小項(xiàng)目,未必需要使用這一模式。但如果是4-5年以上的復(fù)雜大型項(xiàng)目,這種模式的好處就比較明顯了。

如果你是純新手,建議你暫時(shí)不要往下看,先把laravel用得比較熟練后再回來(lái)學(xué)習(xí)。

學(xué)習(xí)Repository Pattern的意義不只是為了使用它,更會(huì)讓你深入思考框架的分層思想,你開(kāi)始不僅關(guān)注怎么使用一個(gè)框架,還會(huì)想了解怎樣設(shè)計(jì)一個(gè)框架,也許會(huì)成為你往高階段編程的入口。

什么是Repository Pattern

雖然說(shuō)設(shè)計(jì)模式和語(yǔ)言及框架無(wú)關(guān),但是脫離了語(yǔ)言及框架,我們很難理解,所以我們還是在laravel的語(yǔ)境下來(lái)學(xué)習(xí)吧:

public function index()
   {
       $posts = Post::whereIn("category_id",[1,2])->where("is_draft",0)->orderBy("created_at", "desc")->take(5)->get();

       return view("front.index",compact("posts"));

   }

以上是典型的Eloquent數(shù)據(jù)查詢代碼,如果你編程經(jīng)驗(yàn)豐富,你會(huì)發(fā)現(xiàn)這種代碼在控制器里到處都是,而且有很多是重復(fù)的,可讀性很差;我們的目標(biāo)是把它精簡(jiǎn):

仔細(xì)觀察

Post::whereIn("category_id",[1,2])->where("is_draft",0)->orderBy("created_at", "desc")->take(5)->get();

其實(shí)它由3部分組成,第一是Post,數(shù)據(jù)模型;第二個(gè)是whereIn("category_id",[1,2])->where("is_draft",0)->orderBy("created_at", "desc")->take(5),數(shù)據(jù)操作條件;第三個(gè)是get(),數(shù)據(jù)獲取的方法;

我們知道,Eloquent里有個(gè)Query Scope,可以用來(lái)把第二部分,也就是查詢條件精簡(jiǎn)。所以,在使用了Query Scope后,我們可以把精簡(jiǎn)成:

Post::ofCategory([1,2])->isDraft()->orderBy("created_at", "desc")->take(5)->get();

咋一看上去,好像也沒(méi)怎么精簡(jiǎn)啊,但實(shí)際上你已經(jīng)實(shí)現(xiàn)代碼解耦和復(fù)用了,比如說(shuō)isDraft(), 這個(gè)代碼可以到處用,而不用擔(dān)心耦合問(wèn)題。

精簡(jiǎn)程度和你的邏輯抽象程度有關(guān),比如說(shuō)你完全可以寫成:

Post::findPosts([1,2],0,"desc",5)->get();

在輕型項(xiàng)目中,強(qiáng)烈推薦使用Query Scope,這是一種良好的編程習(xí)慣。

在更復(fù)雜的項(xiàng)目中,Query Scope就不夠用了,因?yàn)樗蛿?shù)據(jù)模型還是一種強(qiáng)耦合,Repository Pattern就是要把第一,第二,第三部分全部解耦;

說(shuō)到解耦,我們?cè)贚aravel的文檔攻略中講過(guò),第一神器就是PHP中的接口(Interface),下面來(lái)看例子:

第一步——建立文件夾

app

Repositories

Interfaces

Implements

Interfaces里面用來(lái)放接口,Implements用來(lái)放接口的實(shí)現(xiàn);

第二步——建立一個(gè)接口

在上面的Interfaces目錄新建一個(gè)文件PostInterface.php:

namespace AppRepositoriesInterfaces;

Interface PostInterface{
  
  public function findPosts(Array $cat_id,$is_draft,$order,$take){
    
  }
  
  
}

第三步——建立一個(gè)接口對(duì)應(yīng)的實(shí)現(xiàn)

在上面的Implements目錄新建一個(gè)文件PostRepository.php:

namespace AppRepositoriesImplements;

use Post;

class PostRepository Implements PostInterface{
  
  public function findPosts(Array $cat_id,$is_draft,$order,$take){
    
    $query = Post::whereIn("category_id",$cat_id)->where("is_draft",$is_draft)->orderBy("created_at", $order)->take($take)->get();
    
  }
  
}

看這里,很明顯,倉(cāng)庫(kù)指的就是一個(gè)倉(cāng)庫(kù)接口的實(shí)現(xiàn);這里定義你的業(yè)務(wù)邏輯;

第四步——在ServiceProvider中綁定接口

打開(kāi)app/Providers/AppServiceProvider, 在register() 加入代碼:

app->bind("AppRepositoriesInterfacesPostInterface", "AppRepositoriesImplementsPostRepository");
    }
}

我們知道,ServiceProvider是Laravel IOC容器實(shí)現(xiàn)動(dòng)態(tài)換接口實(shí)現(xiàn)的地方,所以我們?cè)谶@里綁定一下,這樣我們?cè)谑褂玫臅r(shí)候,不直接使用接口實(shí)現(xiàn),而是用ioc容器解析接口,它會(huì)幫你自動(dòng)找到對(duì)應(yīng)好的實(shí)現(xiàn)。
這就意味著,以后需要更換實(shí)現(xiàn),可以在這里更換;

第四步——使用倉(cāng)庫(kù)

回到我們的controller里來(lái):

use AppRepositoriesInterfacesPostInterface;

class PostController extends BaseController{
  
    public function __construct(PostInterface $post){
      
        $this->postRepo = $post;
    }
    
    public function index(){
      
      $this->postRepo->findPosts([1,2],0,"desc",5);
    }
  
}

這樣你看,第一,我們的業(yè)務(wù)邏輯變得非常精簡(jiǎn),完全不用管查詢;第二,現(xiàn)實(shí)了數(shù)據(jù)查詢部分的解耦;

到這里,有同學(xué)就會(huì)問(wèn)了,一開(kāi)始說(shuō)好的三個(gè)部分解耦呢,你這里只實(shí)現(xiàn)了第二部分??;

確實(shí),為了最快讓大家明白什么是Repository,我把第一和第二部分的解耦省略了,我們放到這篇文章的系列后續(xù)講。

你或許還有不少疑惑,我費(fèi)那么大勁,寫成最后這個(gè)樣子,好像也沒(méi)什么區(qū)別啊。聰明的同學(xué)可能想到一點(diǎn),如果采用Repository Pattern的話,是不是意味著以后我可以先在controller里寫成$this->postRepo->findPosts([1,2],0,"desc",5); 具體的查詢邏輯先不寫,然后我快速先把 整個(gè)應(yīng)用的業(yè)務(wù)邏輯先跑一遍,然后再回頭一個(gè)一個(gè)寫接口實(shí)現(xiàn)來(lái)支持業(yè)務(wù)邏輯;(哇擦,太NB了,媽媽再也不用擔(dān)心SB客戶/PM改變需求了);

恭喜,你已經(jīng)進(jìn)入高級(jí)編程里說(shuō)的DDD(Domain Driven Design 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))大門了,事實(shí)上,整個(gè)Laravel框架的核心架構(gòu)就是這樣干的,IOC+接口,我們會(huì)在后續(xù)系列文章里介紹;

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

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

相關(guān)文章

  • laravel 開(kāi)發(fā)輔助工具

    摘要:按照最初提出者的介紹,是銜接數(shù)據(jù)映射層和領(lǐng)域?qū)又g的一個(gè)紐帶,作用相當(dāng)于一個(gè)在內(nèi)存中的域?qū)ο蠹???蛻舳藢?duì)象把查詢的一些實(shí)體進(jìn)行組合,并把它們提交給。同時(shí)支持登錄過(guò)期時(shí)間設(shè)置,登錄之前,登錄之后事件處理。 laravel 開(kāi)發(fā)輔助工具 配置 添加服務(wù)提供商 將下面這行添加至 config/app.php 文件 providers 數(shù)組中: providers => [ ... ...

    stormjun 評(píng)論0 收藏0
  • 推薦:好用的 Laravel Repository

    摘要:但在中也不可避免的基礎(chǔ)模式,上述問(wèn)題仍然存在。這樣可以完全分離和的依賴。最開(kāi)始在中使用是通過(guò)定義大量的來(lái)注入,,實(shí)現(xiàn)具體的工作類。但是像鏈接調(diào)用仍然沒(méi)有解決,為些我們開(kāi)發(fā)出了新的倉(cāng)庫(kù)包。目前此包已經(jīng)使用在好幾個(gè)項(xiàng)目中目前運(yùn)行良好。 什么是Repository模式,如何使用Repository模式 這里就不再啰嗦了,請(qǐng)參見(jiàn)以下幾個(gè)鏈接如何使用 Repository 模式?關(guān)于 Repos...

    MAX_zuo 評(píng)論0 收藏0
  • 為什么你應(yīng)該使用 Repository

    摘要:原文來(lái)自模式為了保持代碼的整潔性和可讀性,使用是非常有用的。這是一個(gè)很典型的一段代碼使用和數(shù)據(jù)庫(kù)交互,這段代碼工作的很正常,但是層對(duì)于而言將是緊耦合的。 原文來(lái)自http://vegibit.com/laravel-repository-pattern/ Repository 模式 為了保持代碼的整潔性和可讀性,使用Repository Pattern 是非常有用的。事實(shí)上,我們也不必...

    Simon 評(píng)論0 收藏0
  • MVVM_Android-CleanArchitecture

    摘要:業(yè)務(wù)層,業(yè)務(wù)層,是最為核心的一層。對(duì)于和的狀態(tài)保存恢復(fù)也通過(guò)處理。對(duì)于的綁定操作和命令操作都是暴露的,也易于測(cè)試。需要注意的是標(biāo)簽的節(jié)點(diǎn)中要使用到根節(jié)點(diǎn)中標(biāo)簽里設(shè)置的的話需要這樣設(shè)置抽象類中設(shè)置了和注解,只起到清晰提醒作用。 原文發(fā)表于:Rockos blog(rocko.xyz)] - MVVM_Android-CleanArchitecture 前言 Architecture is...

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

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

0條評(píng)論

tomener

|高級(jí)講師

TA的文章

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