- 容器注入:也叫 依賴注入容器,
使用者在用戶端使用容器來進行類管理,還可以将類的執行個體(對象)做為參數,傳遞給類方法,自動觸發依賴注入。
簡單的講就是将工具類打包成一個容器,在用戶端完成工具類的執行個體化為對象,再以參數的方式直接傳遞給工作類的方法。
- 容器:也稱服務容器,簡稱(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) 也叫 外觀模式 就是将操作進行封裝,對外提供一個統一的接口