依赖注入和控制反转
878 words
2 minutes
Prerequisites
代码的作用
封装调用
- 对于一个程序来说,完全可以写在一个文件中,且从头到尾,需要什么,都直接写,而非封装调用;也就是只通过各个语言编写最基础的cpu指令,比如加减、逻辑运算(或与非等)、流程控制(for|if等),连语言标准库中的函数都不事用
- 也可以对于重复的代码进行封装,待需要的时候进行调用
优雅的代码
- 在我看来,代码的优雅至少应该是:基于逻辑性强、可读性强的一种简洁;所以封装是必须的
- 在封装调用中,就分成了调用方与模块(被调用方);调用方功能的实现是离不开模块的,也就是说调用方是依赖模块的
- 如何调用这些依赖呢?
依赖注入(Dependency Injection)和控制反转(Inversion Of Control)
- 在我看来,控制反转就是以细化功能为前提,降低调用方对模块的依赖,不用管模块的实现方式,达到模块自行控制的目的;
- 依赖注入是控制反转的手段,常用的有构造方法入参,setter方法,这些都是一次性的,就是指不同的调用者调用不同的模块是没有什么优化的
- 这些模块如果是经常被使用的,比如日志服务,那么这些调用就是属于重复操作了,可以再进一步封装,服务容器就是引入一个中间人,经常使用的那些模块先注册,调用方在用的时候直接获取就行了
laravel中的服务容器
- laravel的服务容器就是Illuminate\Foundation\Application
常用的模块绑定到服务容器的方式
1
2
3
| $this->app->bind('HelpSpot\API', function ($app) {
return new HelpSpot\API($app['HttpClient']);
});
|
1
2
3
| $this->app->singleton('FooBar', function ($app) {
return new FooBar($app['SomethingElse']);
});
|
1
2
3
| $fooBar = new FooBar(new SomethingElse);
$this->app->instance('FooBar', $fooBar);
|
1
2
3
4
5
| $this->app->when('App\Handlers\Commands\CreateOrderHandler')
->needs('App\Contracts\EventPusher')
->give(function () {
// Resolve dependency...
});
|
常用的调用方式
1
2
3
4
5
6
7
8
| $this->app->make('TestService');
// 或
$this->app['TestService'];
// 或
App::make('reports');
// 传参的话:
$this->app->makeWith(TestService::class, ['id' => 1]);
// 也可以来个facade直接调方法
|
laravel的服务容器在每一次解析对象时都会触发一个事件,可以使用resolving方法监听该事件
1
2
3
4
5
6
7
| $this->app->resolving(function ($object, $app) {
// 容器解析所有类型对象时调用
});
$this->app->resolving(function (FooBar $fooBar, $app) {
// 容器解析"FooBar"对象时调用
});
|
本文参考