概念理解
我们先来介绍控制反转,依赖注入,这两个概念我们可以认为他们表达的同一种意思,举个通俗的例子,我们用户登录需要提供记录日志的功能,可以选择使用文件或者数据库。下面我们用代码来演示。
// 定义写日志的接口规范
interface log
{
public function write();
}
// 文件记录日志
class FileLog implements Log
{
public function write(){
echo 'file log write...';
}
}
// 数据库记录日志
class DatabaseLog implements Log
{
public function write(){
echo 'database log write...';
}
}
// 程序操作类
class User
{
protected $fileLog;
public function __construct()
{
$this->fileLog = new FileLog();
}
public function login()
{
// 登录成功,记录登录日志
echo 'login success...';
$this->fileLog->write();
}
}
$user = new User();
$user->login();
上面的写法可以实现记录日志的功能,但是有一个问题,假设现在想用数据库记录日志的话,我们就得修改User类,这份代码没达到解耦合,也不符合编程开放封闭原则,那如何修改呢?我们可以把日志处理类通过构造函数方式传递进去。下面我们试着修改User类的代码。
class User
{
protected $log;
public function __construct(Log $log)
{
$this->log = $log;
}
public function login()
{
// 登录成功,记录登录日志
echo 'login success...';
$this->log->write();
}
}
$user = new User(new DatabaseLog());
$user->login();
这样想用任何方式记录操作日志都不需要去修改过User类了,只需要通过构造函数参数传递就可以实现,其实这就是“控制反转”。不需要自己内容修改,改成由外部外部传递。这种由外部负责其依赖需求的行为,我们可以称其为 “控制反转(IoC)”。
那什么是依赖注入呢?,其实上面的例子也算是依赖注入,不是由自己内部new对象或者实例,通过构造函数,或者方法传入的都属于依赖注入(DI) 。
初学laravel的同学应该都比较好奇?很多对象实例通过方法参数定义就能传递进来,调用的时候不需要我们自己去手动传入。下面举一个laravel中实际的例子 Request对象 会都被自动的注入到函数里。是不是比较好奇呢?laravel是如何做到呢?
// routes/web.php
Route::get('/post/store', 'PostController@store');
// App\Http\Controllers
class PostController extends Controller {
public function store(Illuminate\Http\Request $request)
{
$this->validate($request, [
'category_id' => 'required',
'title' => 'required|max:255|min:4',
'body' => 'required|min:6',
]);
}
}
© 著作权归作者所有
发表评论