Our company is now usingLaravel
to develop projects, and also added theBiz
layer and theRepositories
layer to implement business logic encapsulation, butThere is no code in model
.
When writing code inController
, the problem that bothers me is how to reuseBiz
objects,Repositories
objects andModel
Object.
When I usedYii
to develop projects before, there was a factory mode, so when callingModel
, basically nonew
was used, all bytes were usedXXX::model()To call, it is enough for an object to be new once, which can effectively save memory.
Controller code:
$productModel = Product::model()->getList('xxxxxxxxx');
InHow simple, is there any?
Laravel
,Model
seems to have no factory. To call it, an instance is required. IfRepositories
encapsulates 5 methods, each one is used.Model
, then I called these 5 methods inController
, andModel
was new 5 times.
Currently I see a way on the Internet, which is to inject the Model object into the constructor ofRepositories
and put it in the private member variable of Repositories, so that all five methods call the private variable of the current class. That's it. But it is troublesome to use. When writing code in Controller, you need to write like this:
$xxxBiz = new XXXBiz(\xxx\xxx\Repositories);
You need to write this in Repositories:
$xxxRepositories = new XXXRepositories(\xxx\xx\xxxModel);
When creating a newBiz
, theRepositories
object must also be passed in, and the namespace is still long. I basically spell strings, and the writing code is very efficient. Low, I still need to open this file to spell out the name.
I would like to ask how you solve the problem of reuse of logical layer classes such as Model when developing projects with Laravel?
0x0 Preface
Interesting question, Yii is also recognized in the industry as a framework with higher performance than Laravel. So I wanted to look at the specific implementation of the two major frameworks just from the structure of ActiveRecord.
0x1 Eloquent framework for Laravel
It’s easy to use relational queries in Laravel:
I didn’t find the find method in the User class, WTF, what happened! ?
The base class of User is Model, which uses static calling, so the __callStatic magic method of Model will be called:
In fact, it is to call the __call magic method again:
Tracing back to the source, we found that the find method actually comes from IlluminateDatabaseEloquentBuilder, and this class internally uses the implementation of IlluminateDatabaseQueryBuilder.
Wait a minute, what’s the difference betweenIlluminateDatabaseEloquentBuilderandIlluminateDatabaseQueryBuilder?
In fact, EloquentBuilder is a further encapsulation of QueryBuilder to better implement relational object query.
So, the actual process is:
In other words, every time youstatically callthe Model method, the Model will be instantiated and the process will be completed.
0x2 CActiveRecord in Yii 1.1
Since the questioner uses the model method, it should be version 1.1. The module inherits from CActiveRecord (in Yii2, it inherits from YiidbActiveRecord).
Okay, guys, now use Yii to implement relational query, first define:
Enquiry:
Obviously the query object comes from model, let’s see how the parent class implements this function:
findAllByPk method is directly encapsulated inside CActiveRecord:
So the process is:
0x3 Dependency injection using Laravel
Under normal circumstances (parameterless constructor or injected parameters have been configured), Laravel will automatically instantiate it for you:
So you can reuse the same object easily:
After implementing the warehouse, do you need to instantiate it manually:
No, this is not in line with Laravel's philosophy, you can do it as simple as:
Yes, that’s right, you don’t need to manually construct, pass in the User instance, etc., everything is just a simple automatic injection. And the questioner noticed that a namespace is used here, so you only need to use it once. (Of course, if you don’t want to spell such a long namespace, then it’s time for you to change to an IDE. You can use Alt + Enter to quickly import in PhpStorm
0x4 Finally
For the issue of static and non-static overhead, there is a discussion on StackOverflow: http://stackoverflow.com/questions/14727...
So in the final analysis, it still depends on business needs 23333
Through dependency injection
It can be injected directly into the Controller
You can read this article
http://slides.com/howtomakeaturn/model#/
I assume you don’t know much about Laravel yet.
First, Laravel’s Model is also a model, which does not require explicit instantiation. The calling method is as follows (extracted from official documentation):
Second, your description is wrong. What you are looking for is not the factory pattern, but the singleton pattern. The object only needs to be instantiated once during the life cycle of a request. In Laravel, you need to use an IOC (inversion of control) container or service container. Like this:
The above is just a simple excerpt. For specific usage, please refer to Laravel’s official excellent documentation. The link is as follows:
Service Container (IOC container/service container)
Our company inherits a BaseRepository, which is defined in BaseRepository
CouponRepository
Similar in Biz, inherit a BaseBiz, and then write the method like this
Called inController
Controller ---> Biz ---> Repository
This is what I did, create this function in the underlying model
Modify bootstrap/app.php and AppServiceProvider.php
For details, please refer to Service Provider
Just call Foo::load() in the controller