理解依赖注入
Yii2.0 使用了依赖注入的思想。正是使用这种模式,使得Yii2异常灵活和强大。千万不要以为这是很玄乎的东西,看完下面的两个例子就懂了。
class@H_502_8@ SessionStorage { function __construct($cookieName = 'PHP_SESS_ID'@H_502_8@) { session_name($cookieName@H_502_8@); session_start@H_502_8@(); } function set($key,$value@H_502_8@) { $_SESSION[$key] = $value@H_502_8@; } function get($key@H_502_8@) { return $_SESSION[$key@H_502_8@]; } // ... }
这是一个操作session的类 , 下面的user类要使用session中的功能
class@H_502_8@ User { protected $storage@H_502_8@; function@H_502_8@ __construct() { $this->storage = new@H_502_8@ SessionStorage(); } function setLanguage($language@H_502_8@) { $this->storage->set('language',$language@H_502_8@); } function@H_502_8@ getLanguage() { return $this->storage->get('language'@H_502_8@); } // ... }
//我们可以这么调用
$user = new@H_502_8@ User(); $user->setLanguage('zh');
这样看起来没什么问题,但是user里写死了SessionStorage类,耦合性太强,不够灵活,需解耦。
优化后的user类代码
class@H_502_8@ User { protected $storage@H_502_8@; function __construct($storage@H_502_8@) { $this->storage = $storage@H_502_8@; } function setLanguage($language@H_502_8@) { $this->storage->set('language',$language@H_502_8@); } function@H_502_8@ getLanguage() { return $this->storage->get('language'@H_502_8@); } // ... }
$storage = new SessionStorage('SESSION_ID'@H_502_8@); $user = new User($storage);
不在User类中创建SessionStorage对象,而是将storage对象作为参数传递给User的构造函数,这就是依赖注入。
依赖注入的方式
依赖注入可以通过三种方式进行:
构造器注入Constructor Injection
刚才使用的这也是最常见的:
class@H_502_8@ User { function __construct($storage@H_502_8@) { $this->storage = $storage@H_502_8@; } // ... }
设值注入Setter Injection
class@H_502_8@ User { function setSessionStorage($storage@H_502_8@) { $this->storage = $storage@H_502_8@; } // ... }
属性注入Property Injection
下面是Yii2的例子
// create a pagination object with the total count $pagination = new Pagination(['totalCount' => $count@H_502_8@]); // limit the query using the pagination and retrieve the articles $articles = $query->offset($pagination->@H_502_8@offset) ->limit($pagination->@H_502_8@limit) ->all();
参考:http://fabien.potencier.org/what-is-dependency-injection.html