這裏就再也不囉嗦了,請參見如下幾個連接
如何使用 Repository 模式?
關於 Repository 的設計模式
laravel-china.org搜索laravel
MVC
在現在仍然是流行趨勢,但多數框架都只提供基礎的MVC
架構。
幾年前在開發中咱們常常會遇到問題Model
過於臃腫,寫着寫着就會變成相似於萬能類,最後面的人就真成了接盤俠了。
很不幸我就是其中之一。後來我就一直在思考如何才能讓Model
看起來清爽,功能更加單一簡潔。(當時並不知道Repository
),終於開始重構。一把心酸淚。。。。。最多的是組合和Trait
git
最開始接觸Laravel就是感受它的文檔清爽,覺得是個簡單的框架,結果不當心一入坑,才發現被它的外表給欺騙了。
但卻也爲此深深愛上了它,是啊,這不就是我一直追求的嗎?無限的靈活性,可替換,越研究代碼愈加現到處都是精髓。
但在Laravel
中也不可避免的基礎MVC
模式,上述問題仍然存在。github
一直覺得我都遵循一個核心:以倉庫層爲處理數據基礎,爲Serivce
和Controller
等提供數據供給,倉庫須要的原始數據則經過Model
中獲取。這樣能夠徹底分離Model
和Controller
的依賴。
最開始在Laravel
中使用是經過定義大量的RepositoryInterface
來注入,bind
,實現具體的Repository
工做類。
這是理想的使用方法可替換性很強。設計模式
Repository
基本不會被替換,無數的Interface
帶來的規範,也帶來了開發的麻煩。Repository
模式中咱們不斷的注入Model
,每一個方法都須要直接Model
來進行一次次的查詢數據集,卻失去了在外層鏈式調用的便捷性(這其實並不合理,但存在即有起因)。後來索性在開發中咱們去掉了Interface
的約束,直接做用功能類來注入使用,此時簡潔性和便捷性大大的提升,若是非要替換仍然bind
能夠解決問題。這樣的開始一直持續很長時間。可是像連接調用仍然沒有解決,爲些咱們開發出了新的倉庫包。https://github.com/crcms/repository架構
開始玩微服務,開始分離代碼,固然就離不開RPC
,十分慶幸咱們使用了Repository
模式,經過開啓對應的Rpc Repository
,咱們能夠很快進行本地Repository
切換,以Interface
來約束。app
class TestRepository extends AbstractRepository { /** * @var array */ protected $guard = [ 'id', 'title','other' ]; /** * @return TestModel */ public function newModel(): TestModel { return app(TestModel::class); } /** * @param int $perPage * @return LengthAwarePaginator */ public function paginate(AbstractMagic $magic = null, int $perPage = 15): LengthAwarePaginator { $query = $this->where('built_in', 1); if ($magic) { $query->magic($magic); } return $query->orderBy($this->getModel()->getKeyName(), 'desc')->paginate($perPage); } /** * @param int $name * @param int $title */ public function updateName(string $name, string $title) { $this->getModel()->where('name', $name)->update(['title' => $title]); } }
在多條件搜索中,確定會存在大量的判斷,優雅度過低,如:框架
if($request->input('username')) { $query->where('username',$username) } if($request->input('email')) { $query->where('email',$email) } .......
但經過QueryMagic
方法咱們能夠輕鬆優雅解決這些問題,示例:微服務
建立Magic
類ui
use CrCms\Repository\AbstractMagic; use CrCms\Repository\Contracts\QueryRelate; class TestMagic extends AbstractMagic { /** * @param QueryRelate $queryRelate * @param int $id * @return QueryRelate */ protected function byName(QueryRelate $queryRelate, string $name) { return $queryRelate->where('name', $name); } /** * @param QueryRelate $queryRelate * @param string $title * @return QueryRelate */ protected function byTitle(QueryRelate $queryRelate, string $title) { return $queryRelate->where('title', 'like', "%{$title}%"); } /** * @param QueryRelate $queryRelate * @param int $id * @return QueryRelate */ protected function byId(QueryRelate $queryRelate, int $id) { return $queryRelate->where('id', $id); } }
使用Magic
(這裏只是簡單示例):this
public function paginate(array $condition, int $perPage = 15): LengthAwarePaginator { return $query->magic(new TestMagic($condition))->orderBy($this->getModel()->getKeyName(), 'desc')->paginate($perPage); }
開發此包的緣由是在這以前我並示找到我想要的(適合個人)兼具Model
的靈活性以及數據倉庫的分離模式,因此爲此開發了這個倉庫包。目前此包已經使用在好幾個項目中目前運行良好。
後面還打算兼容TP
以及Yii
等使用率高的框架,暫時只支持Laravel
更多詳情,請移步github:https://github.com/crcms/repository
哈哈,請原諒我着急的文本描述,但願對須要的人以及面臨和我曾經同樣困惑的人有所幫助。
原文出處:crcms-blog