- 容器注入:也叫 依赖注入容器,
用户在客户端使用容器来进行类管理,还可以将类的实例(对象)做为参数,传递给类方法,自动触发依赖注入。
简单的讲就是将工具类打包成一个容器,在客户端完成工具类的实例化为对象,再以参数的方式直接传递给工作类的方法。
- 容器:也称服务容器,简称(IOC)类似于:[即插即用]的工具,最大限度的简化外部对象的调用
- 实现步骤有三步:
创建工具类
//数据库操作类
class Db
{
//数据库连接
public function connect()
{
return '数据库连接成功<br>';
}
}
//数据验证类
class Validate
{
//数据验证
public function check()
{
return '数据验证成功<br>';
}
}
//视图
class View
{
//内容输出
public function display()
{
return '用户登录成功';
}
}
一、创建容器类:将类与类的实例化过程绑定到容器中(不局限于类,也可是接口或其它)
class Container
{
//创建属性,用空数组初始化,该属性用来保存类与类的实例化方法
protected $instance = [];
//初始化实例数组,将需要实例化的类,与实例化的方法进行绑定
public function bind($abstract, Closure $process)
{
//键名为类名,值为实例化的方法
$this->instance[$abstract] = $process;
}
//创建类实例
public function make($abstract, $params=[])
{
return call_user_func_array($this->instance[$abstract],[]);
}
}
二、服务绑定:将可能用到的工具类全部绑定到容器中
服务注册:将类实例注册到容器中
$container = new Container();
//将Db类绑定到容器中
$container->bind('db', function(){
return new Db();
});
//将Validate类实例绑定到容器中
$container->bind('validate', function(){
return new Validate();
});
//将View类实例绑定到容器中
$container->bind('view', function(){
return new View();
});
三、容器依赖:将容器对象,以参数的方式注入到当前工作类中
依赖容器:调用工作类时直接传入容器对象即可,工具类的实例化由容器完成
//用户类:工作类
class User
{
//用户登录操作
// public function login(Db $db, Validate $validate, View $view)
//此时,只需从外部注入一个容器对象即可,Db,Validate和View实例方法全部封装到了容器中
public function login(Container $container)
{
//实例化Db类并调用connect()连接数据库
echo $container->make('db')->connect();
//实例化Validate类并调用check()进行数据验证
echo $container->make('validate')->check();
//实例化视图类并调用display()显示运行结果
echo $container->make('view')->display();
}
}
客户端调用
//创建User类
$user = new User();
//调用User对象的login方法进行登录操作
//将该类依赖的外部对象以参数方式注入到当前方法中,推荐以构造器方式注入
echo '<h3>用依赖容器进行解藕:</h3>';
//工作类中的login方法不需要写三个对象了,只需要一个容器对象即可
echo $user->login($container);
下面案例使用依赖注入的思路是APP用到A类,A类需要B类,B类需要C类。那么先创建C类,再创建B类并把C注入,再创建A类,并把B类注入,再调用A方法,A调用B方法,接着做些其它工作。
<?php
class C
{
public function doSomething()
{
echo __METHOD__, '我是C类|';
}
}
class B
{
private $c;
public function __construct(C $c)
{
$this->c = $c;
}
public function doSomething()
{
$this->c->doSomething();
echo __METHOD__, '我是B类|';
}
}
class A
{
private $b;
public function __construct(B $b)
{
$this->b = $b;
}
public function doSomething()
{
$this->b->doSomething();
echo __METHOD__, '我是A类|';;
}
}
class Container
{
private $s = array();
function __set($k, $c)
{
$this->s[$k] = $c;
}
function __get($k)
{
return $this->s[$k]($this);
}
}
$class = new Container();
$class->c = function () {
return new C();
};
$class->b = function ($class) {
return new B($class->c);
};
$class->a = function ($class) {
return new A($class->b);
};
// 从容器中取得A
$foo = $class->a;
$foo->doSomething(); // C::doSomething我是C类|B::doSomething我是B类|A::doSomething我是A类|
- 门面模式(facade) 也叫 外观模式 就是将操作进行封装,对外提供一个统一的接口