对于IOC(控制反转)和依赖注入的理解
2018-01-03 本文已影响0人
phpdi
以下都是我自己的理解,仅做参考。
1.控制反转:
是面向对象编程的一种设计原则思想。控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。例如:A对象的创建依赖B对象,控制正转:直接在A类中创建出B对象。控制反转:现在外部创建好B对象,然后传递给A类。都是解决依赖。控制反转的优点是,不会将依赖硬性编码到A类的内部。以致于系统庞大后,造成难以维护的情况。
2.依赖注入:
只要不是由内部生产(比如初始化、构造函数__construct 中通过工厂方法、自行手动new 的),而是由外部以参数或其他形式注入的,都属于依赖注入(DI) 。
//以下是一个超人对象,依赖各种能力对象的,ioc容器实现的例子。
/**
* Interface SuperModuleInterface
* 定义一个超能力接口
*/
interface SuperModuleInterface
{
/**
* 超能力激活方法
*
* 任何一个超能力都得有该方法,并拥有一个参数
* @param array $target 针对目标,可以是一个或多个,自己或他人
*/
public function activate();
}
class Xpower implements SuperModuleInterface
{
public function activate()
{
// TODO: Implement activate() method.
echo 'xpower执行能力';
}
}
class UltrBomb implements SuperModuleInterface
{
public function activate()
{
// TODO: Implement activate() method.
echo 'ultrbomb执行能力';
}
}
class Superman
{
protected $module;
public function __construct(SuperModuleInterface $module)
{
$this->module = $module;
}
public function __call($name, $arguments)
{
// TODO: Implement __call() method.
$this->module->$name();
}
}
/**
* Class Container
* ioc容器,调度中心,帮助对象获取依赖,并注入到对象中
*/
class Container
{
protected $binds;
protected $instances;
/**
* 名称:bind用来记录怎么制造对象
*/
public function bind($abstract, $concrete)
{
if ($concrete instanceof Closure) {
$this->binds[$abstract] = $concrete;//此时闭包函数并不会执行,因为没有调用它
}else {
$this->instances[$abstract] = $concrete;
}
}
/**
* 名称:make方法用来制造对象。
*/
public function make($abstract, $parameters = [])
{
//存在对象直接返回
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}
//将容器插入到参数中
array_unshift($parameters, $this);
//这里调用了bind绑定进来的闭包函数,返回对象,$parameters这个参数会作为闭包的参数,传入闭包当中
return call_user_func_array($this->binds[$abstract], $parameters);
}
}
//创建一个容器
$container = new Container;
//添加生产superman对象的脚本,告诉容器怎么制造superman这个对象
$container->bind('superman', function ($container, $moduleName) {
//这里生产superman,需要一个SuperModuleInterface 类型的能力对象,直接由容器来制造对象,然后传递给Superman类使用。
return new Superman($container->make($moduleName));
});
//告诉容器怎么制造xpower这个对象
$container->bind('xpower', function ($container) {
return new Xpower;
});
//告诉容器怎么制造ultrabomb这个对象
$container->bind('ultrabomb', function ($container) {
return new UltrBomb;
});
$superman_1 = $container->make('superman', ['xpower']);
$superman_2 = $container->make('superman', ['ultrabomb']);
$superman_1->activate();
$superman_2->activate();