我們有三個類,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