控制反转
不需要自己内容修改,改成由外部传递。这种由外部负责其依赖需求的行为,我们可以称其为 控制反转(IoC)
。
举例说明:如果要定义一个日记记录功能,可以用文本,也可以用数据库记录,并且用户可以自由选择文本或数据库
// 定义写日志的接口规范
interface Log
{
public function write();
}
// 文件记录日志
class FileLog implements Log
{
public function write(){
echo 'file log write...';
}
}
// 数据库记录日志
class DatabaseLog implements Log
{
public function write(){
echo 'database log write...';
}
}
// 程序操作类
class User
{
protected $fileLog;
public function __construct()
{
$this->fileLog = new FileLog();
}
public function login()
{
// 登录成功,记录登录日志
echo 'login success...';
$this->fileLog->write();
}
}
$user = new User();
$user->login();
上面这种形式有缺陷,如果需要修改成使用数据库记录,就会导致要改 User
类,所以最终要用何种形式来记录日志,应该由外部来自行选择,修改代码如下:
class Use
{
protected $log;
// 通过构造方法传参来选择使用何种形式记录日志
public function __construct(Log $log)
{
$this->log = $log;
}
public function login()
{
// 登录成功,记录登录日志
echo 'login success...';
$this->log->write();
}
}
$user = new User(new DatabaseLog());
$user->login();
依赖注入
不是由自己内部 new 对象或者实例,通过构造函数,或者方法传入的都属于 依赖注入(DI)
上文的也是 依赖注入