今天看到一篇文章,讲了关于Laravel依赖注入的小例子,觉得角度很好转载过来做个笔记。
第一个例子
interface Visit
{
public function go();
}
class Leg implements Visit //行走接口
{
public function go()
{
// TODO: Implement go() method.
echo "walt to Tibet!!!";
}
}
class Car implements Visit //汽车接口
{
public function go()
{
// TODO: Implement go() method.
echo "drive car to Tibet!!!";
}
}
class Train implements Visit //火车接口
{
public function go()
{
// TODO: Implement go() method.
echo "go to Tibet by train";
}
}
class Traveller // 旅行者类
{
protected $trafficTool;
public function __construct()
{
$this->trafficTool =new Leg(); // 产生依赖
}
public function visitTibet()
{
$this->trafficTool->go();
}
}
$tra = new Traveller();
$tra->visitTibet();
我们要实现的功能是旅游者去西藏,但是去西藏的方式有很多,走路、开车或者火车。不同的方式需要依靠不同的交通工具
在古代交通基本靠走,通讯基本靠吼。所以旅游西藏的交通工具就是我们的大腿 Leg 所以我们在代码$this->trafficTool =new Leg(); 实例化了腿
于是上述的两个组件就发生了依赖,因为我们去西藏旅行需要靠大腿走去
在程序中依赖我们可以理解成为一个对象实现某个功能需要其它对象相关功能的支持
但是我们使用 new 实例化对象解决了依赖,但是我们同时也引入的一个新的严重问题 耦合
在古代走去西藏当然没毛病,但是现在21世纪交通工具这么发达,再走去西藏就真的很皮了
所以这时我们选择做火车,毕竟有青藏铁路 。但是这时候我们就头大了,要改成做火车去西藏那么我们就要重写 Traveller 类 在里面实例化 Train 接口
这个例子的最大问题就是在使用类的时候如果要变更接口需要在类的代码中重新修改实例化代码,从而造成解耦的问题,如果同时需要两种接口则需要一个重复的类。
下面看第二个例子
interface Visit
{
public function go();
}
class Leg implements Visit //行走接口
{
public function go()
{
// TODO: Implement go() method.
echo "walt to Tibet!!!";
}
}
class Car implements Visit //汽车接口
{
public function go()
{
// TODO: Implement go() method.
echo "drive car to Tibet!!!";
}
}
class Train implements Visit //火车接口
{
public function go()
{
// TODO: Implement go() method.
echo "go to Tibet by train";
}
}
class Traveller // 旅行者类
{
protected $trafficTool;
public function __construct(Visit $trafficTool)
{
$this->trafficTool = $trafficTool;
}
public function visitTibet()
{
$this->trafficTool->go();
}
}
$tra = new Traveller(new Car());
$tra->visitTibet();
Traveller 类的构造函数依赖了一个外部的具有visit接口的实例,而实例化Traveller时,我们传递了一个 $trafficTool 实例, 即通过依赖注入的方法解决依赖
Ioc (Inversion of Control) 控制反转模式 又称 (Depe-ndency Injection)依赖注入模式
控制反转是将组件的依赖关系从程序内部提到程序外部来管理,而依赖注入是指组件的依赖通过外部以参数或其它形式注入