Unser Unternehmen verwendet derzeit Laravel
开发项目,同时还增加了Biz
层和Repositories
层,来实现业务逻辑封装,反而model
里面什么代码都没有。
在Controller
里写代码的时候,尝尝困扰我的问题是如果复用Biz
对象,Repositories
对象和Model
对象。
以前用Yii
开发项目的时候,有一个工厂模式,所以调用Model
的时候,基本都不new
, das als Bytes mit XXX::model() bezeichnet wird. Es reicht aus, wenn ein Objekt einmal neu ist, was effektiv Speicher sparen kann. Controller-Code:
$productModel = Product::model()->getList('xxxxxxxxx');
Wie einfach, oder?In
Laravel
scheint Model
keine Factory zu haben. Um es aufzurufen, ist eine Instanz erforderlich. Wenn Repositories
5 Methoden kapselt, ist jede davon vorhanden habe Model
verwendet, dann habe ich diese 5 Methoden in Controller
aufgerufen und Model
war fünfmal neu. Ich sehe derzeit im Internet eine Möglichkeit, das Modellobjekt in den Konstruktor von Repositories
einzufügen und in die privaten Mitgliedsvariablen von Repositories einzufügen. Auf diese Weise können alle fünf Methoden aufrufen private Variablen der aktuellen Klasse. Die Verwendung ist jedoch umständlich. Wenn Sie Code in Controller schreiben, müssen Sie so schreiben: Laravel
里,Model
好像没有工厂,要调用,都需要实例,假如Repositories
里面封装了5个方法,每个都使用了Model
,那么我在Controller
里调用了这5个方法,Model
就被new了5次。
目前在网上看到一种办法,就是在Repositories
$xxxBiz = new XXXBiz(\xxx\xxx\Repositories);
Sie müssen dies in Repositories schreiben:
$xxxRepositories = new XXXRepositories(\xxx\xx\xxxModel);
Es gibt ein -Objekt in new, und der Namespace ist im Grunde immer noch lang, und die Effizienz beim Schreiben von Code ist extrem gering. Außerdem muss ich die Datei öffnen, um den Namen zu buchstabieren. Biz
的时候,还必须传入Repositories
Ich würde gerne fragen, wie Sie das Problem der Wiederverwendung logischer Schichtklassen wie Model bei der Entwicklung von Projekten mit Laravel lösen?
0x0 前言
有趣的问题,Yii 在业界也是被公认为性能比 Laravel 高的一个框架。于是我想单从 ActiveRecord 的构造,看看两大框架的具体实现。
0x1 Laravel 的 Eloquent 框架
在 Laravel 中可以很轻松地使用关系查询:
我在 User 类里并没有找到 find 方法,WTF,发生了什么!?
User 的基类是 Model,使用静态调用,所以会调用 Model 的 __callStatic 魔术方法:
其实就是再调用 __call 魔术方法:
追根溯源,我们发现其实 find 方法来自 Illuminate\Database\Eloquent\Builder,而该类内部使用 Illuminate\Database\Query\Builder 的实现。
等等,Illuminate\Database\Eloquent\Builder 和 Illuminate\Database\Query\Builder 的区别是啥?
其实 Eloquent\Builder 是对 Query\Builder 的进一步封装,以便更好的实现关系对象查询。
那么,其实过程为:
也就是说,你每次 静态调用 Model 的方法,都会实例化一次 Model,走一次过程。
0x2 Yii 1.1 中的 CActiveRecord
题主既然用到 model 方法,那应该是 1.1 的版本,模块继承自 CActiveRecord(Yii2 中则继承自 Yii\db\ActiveRecord)。
好了,伙计们,现在使用 Yii 实现关系查询,先定义:
查询:
明显查询对象来自 model,看看父类怎么实现这个函数:
findAllByPk 方法直接封装于 CActiveRecord 内部:
所以其过程为:
0x3 使用 Laravel 的依赖注入
通常情况下(无参数的构造函数或注入参数已配置),Laravel 会自动帮你实例化:
所以你可以很轻松复用同一个对象:
实现完仓库后,你需要手动实例化吗:
不,这不符合 Laravel 的哲♂学,你可以如此简单:
是的,没错,你无需手动构造,传入 User 实例等等,一切只是一个简单的自动注入。而且题主注意到这里使用了命名空间,所以你只需 use 一次。(当然如果你不想拼写这么长的命名空间,那你是时候换一款 IDE 了,PhpStorm 中可以使用 Alt + Enter 快速导入
0x4 最后
对于静态和非静态开销的问题,在 StackOverflow 上有一篇讨论:http://stackoverflow.com/questions/14727...
所以说到底还是看业务需求嘛23333
通过依赖注入呀
直接可以注入到Controller中
可以看看这个文章
http://slides.com/howtomakeaturn/model#/
我假定你对Laravel还不是很了解。
第一,Laravel的Model也就是模型,不需要显式的实例化,调用方式像下面这样(摘自官方文档):
第二,你的描述有错误。你寻找的不是工厂模式(factory pattern),而是单例模式(singleton pattern),对象在一次请求生命周期之内,最多只需要实例化一次。在Laravel当中,需要用到IOC(inversion of control)容器或者说是服务容器(service container)。像下面这样:
以上只是简单的摘录,具体用法,请参考Laravel官方优秀的文档,链接如下:
Service Container(IOC容器/服务容器)
我司是继承一个BaseRepository,BaseRepository中定义
CouponRepository中
Biz中类似,继承一个BaseBiz,然后方法这么写
Controller中调用
Controller ---> Biz ---> Repository
我是这么做的,在底层 model 里建立这个函数
修改bootstrap/app.php 和 AppServiceProvider.php
具体参考 Service Provider
在controller 里调用 Foo::load() 就可以了