Laravel服务容器
- IoC(控制反转)
- DI(依赖注入)
Laravel服务容器是一个用于管理类依赖和执行依赖注入的强大工具
IoC(控制反转)与DI(依赖注入)
IoC(控制反转)与DI(依赖注入)是现在特别流行的概念,也是目前降低软件开发复杂度;提升模块低耦合、高内聚所使用的一种设计模式。
控制反转与IoC容器
控制反转:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源;
控制反转是用来进行对象解耦。通过借助第三方(IoC容器),将具有依赖关系的对象进行解耦。
比如全体齿轮的转动由一个对象来控制,如类B。如下图所示:
引入了IoC容器后,对象A、B、C、D之间没有了依赖关系,全体齿轮转动的控制权交给IoC容器。这 时候齿轮转动控制权不属于任何对象,而属于IoC容器,所以控制权反转了,从某个对象转到了IoC容 器。
依赖注入
依赖注入,首先依赖就是指一种关系,如果在类A中创建了类B的实例,我们就可以说类A依赖类B。
例如:
<?php
class B {
public function func() {
print_r(__CLASS__);
}
}
class A {
private $b;
public function A() {
$this->b = new B();
}
public function func() {
$this->b->func();
}
}
而使用这种方式,则会出现以下问题:
- 问题1:如果现在要改变类B的创建方式,如需要用new B(String name)初始化B,需要修改类A中的源代码;
- 问题2:如果想测试不同B对象对A的影响很困难,因为B的初始化被写死在了A的构造函数中;
- 问题3:如果要对类B的实例进行调试时,就必须在类A中对类B的实例进行测试,增加了测试难度和复杂度;因为当出现问题时,不知道是类A的问题 还是类B的问题。基于此,提出以下的解决方案:
<?php
class A {
private $b;
public function A(B $bObj) {
$this->b = $bObj;
}
public function func() {
$this->b->func();
}
}
将B对象实例作为类A的构造器参数进行传入,在调用类A构造器之前,类B实例已经被初始化好了。像这种非自己主动初始化依赖,而通过外部传入依赖对象的方式,就很完美的解决了上述的问题,这就是依赖注入。
<?php
//Ioc ———— 设计方式
//控制反转 Inversion of Control
//依赖关系的转移
//依赖抽象而非实践
//用于解决高层应用依赖 底层组件,软件移植性差(修改困难)的问题
//实例:
/*
class soft{
private $writer;
public function __construct(){
$this->writer = new FloppyWriter;
}
public function save(){
$this->writer->SaveToFloppy();
}
}
//造成高层对底层的依赖__使程序无法重用 不好的设计
class FloppyWriter{
public function saveToFloppy(){
echo __METHOD__;
}
}
$soft = new soft;
$soft->save()
*/
##########################改进##########################
//定义一个接口约定
interface IDeviceWriter
{
public function saveToDevice();
}
class soft{
private $_writer;
public function setWriter($name){
$this->_writer = $name;
}
public function save(){
$this->_writer->saveToDevice();
}
}
//软盘储存
class FoppyWriter implements IDeviceWriter{
public function saveToDevice(){
echo __METHOD__;
}
}
//USB储存
class USBWriter implements IDeviceWriter{
public function saveToDevice(){
echo __METHOD__;
}
}
//将高层依赖 转移到 "依赖注入"
$soft= new soft();
$writer= new USBWriter;
$soft->setWriter( $writer);
$soft->save();