我們有三個類,Db,FileSystem,Session;實際業務需求要組合操作這三個類.
一.常規做法
class Db
{
public function read($id)
{
}
}
class FileSystem
{
public function writeFile($file)
{
}
}
class Session
{
public function setSession($sessionName)
{
}
}
// 實際邏輯
class Logic
{
protected $db;
protected $file;
protected $session;
public function __construct()
{
$this->db = new Db();
$this->file = new FileSystem();
$this->session = new Session();
}
public function handle($id)
{
if ($name = $this->db->read($id)) {
$this->file->writeFile(md5($name) . '.txt');
$this->session->setSession($id);
}
}
}
$id = 11;
$client = new Logic();
$client->handle($id);
缺點:
Logic內部高度耦合了,Db,FileSystem,Session
如果這三個類的初始化條件變化,則需要修改Logic的構造方法.
二.參數依賴(類型提示,將新建關聯類的放入調用處)
修改Logic代碼如下:
class Logic
{
protected $db;
protected $file;
protected $session;
public function __construct(Db $db, FileSystem $file, Session $session)
{
$this->db = $db;
$this->file = $file;
$this->session = $session;
}
public function handle($id)
{
if ($name = $this->db->read($id)) {
$this->file->writeFile(md5($name) . '.txt');
$this->session->setSession($id);
}
}
}
$id = 11;
$db = new Db();
$file = new FileSystem();
$session = new Session();
$client = new Logic($db, $file, $session);
$client->handle($id);
優點:
實現了解耦
缺點:
業務變動,如果要更改Db類到MySql類或初始化條件變動,代碼依然要改動.
ps:大部分的設計模式使用了該解耦方法.
三.容器
1.希望DB類,Session類,FileSystem類“拿來即用”,不用每次繁瑣的初始化,比如寫$db=new DB(arg1,arg2);這類語句。
2.希望DB等類型的對象是“全局”,在整個程序運行期間,隨時可以調用。
3.調用DB等類型的程序員不用知道這個類太多的細節,甚至可以用一個字符串的別名來創建這樣一個對象。
能夠實現以上目標的就是IOC容器,可以把IOC容器簡單的看成一個全局變量,並用關聯數組把字符串和構造函數做綁定
// 容器
class Container
{
public $binds = array();
public function bind($abstract, $concreate)
{
$this->binds[$abstract] = $concreate;
}
public function make($abstract, $params = [])
{
return call_user_func_array($this->binds[$abstract], $params);
}
}
// 綁定或注冊
$container = new Container();
$container->bind('db', function () {
return new Db();
});
$container->bind('file', function () {
return new FileSystem();
});
$container->bind('session', function () {
return new Session();
});
// 實際邏輯,容器依賴
class Logic
{
protected $db;
protected $file;
protected $session;
public function __construct(Container $container)
{
$this->db = $container->make('db');
$this->file = $container->make('file');
$this->session = $container->make('session');
}
public function handle($id)
{
if ($name = $this->db->read($id)) {
$this->file->writeFile(md5($name) . '.txt');
$this->session->setSession($id);
}
}
}
$id = 11;
$logic = new Logic($container);
$logic->handle($id);
本文參考自:https://www.cnblogs.com/sweng/p/6430374.html
