依赖注入和控制反转

控制反转(IOC)

Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制

  • 如何理解?
    要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”
    通常我们是在程序(消费者)里边直接new一个新对象(被依赖对象),创建一个依赖的对象。

1.谁来控制谁:Ioc有一个专门的容器,来创建这些对象(外部资源),而不是由(消费者显示使用new)。
2.控制什么?那就是主要控制了外部资源获取和生命周期(不只是对象也包括文件等)
3.为何是反转?
3.1 传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;
3.2 而反转则是由容器来帮忙创建及注入依赖对象;
4.为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;
5.哪些方面反转了?依赖对象的获取被反转了。

依赖注入(DI)

是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中.
依赖是为了提高组件重用频率,且扩展更加方便灵活。

  • 如何理解
    理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”
    1.谁依赖于谁:当然是应用程序依赖于IOC容器;
    2.为什么需要依赖:应用程序需要IOC容器来提供对象需要的外部资源;
    3.谁注入谁:很明显是IOC容器注入应用程序某个对象,应用程序依赖的对象;
    4.注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

  • 常用实现方法

    1. 构造函数注入
    2. setMethod()注入
    3. 通过接口定义注入方法,程序实现该方法
  • Ioc demo

/**
 * 控制反转类
 */
class Ioc {
    /**
     * @var array 注册的依赖数组
     */
    protected static $registry = array();

    /**
     * 添加一个 resolve (匿名函数)到 registry 数组中
     *
     * @param string  $name    依赖标识
     * @param Closure $resolve 一个匿名函数,用来创建实例
     * @return void
     */
    public static function register($name, Closure $resolve) {
        static::$registry[$name] = $resolve;
    }

    /**
     * 返回一个实例
     *
     * @param string $name 依赖的标识
     * @return mixed
     * @throws \Exception
     */
    public static function resolve($name) {
        if (static::registered($name)) {
            $name = static::$registry[$name];
            return $name();
        }

        throw new \Exception("Nothing registered with that name");
    }

    /**
     * 查询某个依赖实例是否存在
     *
     * @param string $name
     * @return bool
     */
    public static function registered($name) {
        return array_key_exists($name, static::$registry);
    }
}

/**
-- Usage:

Ioc::register("book", function () {
    $book = new Book();
    $book->setdb('db');
    $book->setfile('file');

    return $book;
});

// 注入依赖
$book = Ioc::resolve('book');

 */

参考
对IOC和DI的通俗理解
PHP 依赖注入(DI) 和 控制反转(IoC)
"深入理解DIP、IoC、DI以及IoC容器"

posted @ 2022-04-02 11:44  FZ-august  阅读(68)  评论(0)    收藏  举报