这里就再也不啰嗦了,请参见如下几个连接
如何使用 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