控制反转

不需要自己内容修改,改成由外部传递。这种由外部负责其依赖需求的行为,我们可以称其为 控制反转(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) 上文的也是 依赖注入