以下都是我自己的理解溶推,僅做參考碍脏。
1.控制反轉(zhuǎn):
是面向?qū)ο缶幊痰囊环N設(shè)計原則思想否灾÷羯茫控制反轉(zhuǎn)一般分為兩種類型,依賴注入(Dependency Injection墨技,簡稱DI)和依賴查找(Dependency Lookup)惩阶。例如:A對象的創(chuàng)建依賴B對象,控制正轉(zhuǎn):直接在A類中創(chuàng)建出B對象扣汪《峡控制反轉(zhuǎn):現(xiàn)在外部創(chuàng)建好B對象,然后傳遞給A類崭别。都是解決依賴冬筒。控制反轉(zhuǎn)的優(yōu)點是茅主,不會將依賴硬性編碼到A類的內(nèi)部舞痰。以致于系統(tǒng)龐大后,造成難以維護的情況诀姚。
2.依賴注入:
只要不是由內(nèi)部生產(chǎn)(比如初始化响牛、構(gòu)造函數(shù)__construct 中通過工廠方法、自行手動new 的),而是由外部以參數(shù)或其他形式注入的呀打,都屬于依賴注入(DI) 矢赁。
//以下是一個超人對象,依賴各種能力對象的贬丛,ioc容器實現(xiàn)的例子撩银。
/**
* Interface SuperModuleInterface
* 定義一個超能力接口
*/
interface SuperModuleInterface
{
/**
* 超能力激活方法
*
* 任何一個超能力都得有該方法,并擁有一個參數(shù)
* @param array $target 針對目標(biāo)瘫寝,可以是一個或多個蜒蕾,自己或他人
*/
public function activate();
}
class Xpower implements SuperModuleInterface
{
public function activate()
{
// TODO: Implement activate() method.
echo 'xpower執(zhí)行能力';
}
}
class UltrBomb implements SuperModuleInterface
{
public function activate()
{
// TODO: Implement activate() method.
echo 'ultrbomb執(zhí)行能力';
}
}
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容器稠炬,調(diào)度中心焕阿,幫助對象獲取依賴,并注入到對象中
*/
class Container
{
protected $binds;
protected $instances;
/**
* 名稱:bind用來記錄怎么制造對象
*/
public function bind($abstract, $concrete)
{
if ($concrete instanceof Closure) {
$this->binds[$abstract] = $concrete;//此時閉包函數(shù)并不會執(zhí)行首启,因為沒有調(diào)用它
}else {
$this->instances[$abstract] = $concrete;
}
}
/**
* 名稱:make方法用來制造對象暮屡。
*/
public function make($abstract, $parameters = [])
{
//存在對象直接返回
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}
//將容器插入到參數(shù)中
array_unshift($parameters, $this);
//這里調(diào)用了bind綁定進來的閉包函數(shù),返回對象毅桃,$parameters這個參數(shù)會作為閉包的參數(shù)褒纲,傳入閉包當(dāng)中
return call_user_func_array($this->binds[$abstract], $parameters);
}
}
//創(chuàng)建一個容器
$container = new Container;
//添加生產(chǎn)superman對象的腳本,告訴容器怎么制造superman這個對象
$container->bind('superman', function ($container, $moduleName) {
//這里生產(chǎn)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();