思考并回答以下问题:
- 用递归的方式创建参数依赖。怎么理解?
概念理解
我们先来介绍控制反转,依赖注入,这两个概念我们可以认为他们表达的同一种意思,举个通俗的例子,我们用户登录需要提供记录日志的功能,可以选择使用文件或者数据库。下面我们用代码来演示。
1 | // 定义写日志的接口规范 |
上面的写法可以实现记录日志的功能,但是有一个问题,假设现在想用数据库记录日志的话,我们就得修改User类,这份代码没达到解耦合,也不符合编程开放封闭原则,那如何修改呢?我们可以把日志处理类通过构造函数方式传递进去。下面我们试着修改User类的代码。
1 | class User |
这样想用任何方式记录操作日志都不需要去修改User类了,只需要通过构造函数传递参数就可以实现,其实这就是“控制反转”。不需要自己内容修改,改成由外部传递。这种由外部负责其依赖需求的行为,我们可以称其为 “控制反转(IoC)”。
那什么是依赖注入呢?其实上面的例子也算是依赖注入,不是由自己内部new对象或者实例,通过构造函数,或者方法传入的都属于依赖注入(DI) 。
依赖注入
初学Laravel的同学应该都比较好奇,很多对象实例通过方法参数定义就能传递进来,调用的时候不需要我们自己去手动传入。下面举一个Laravel中实际的例子,Request对象会被自动的注入到函数里。
1 | // routes/web.php |
反射理解
我们现在已经明白了依赖注入的概念。那Laravel那种用法怎么实现呢?可能有些同学已经想到了这里面肯定会用到反射机制去创建动态Post,然后去调用store方法。
反射的概念其实可以理解成根据类名返回该类的任何信息,比如该类有什么方法,参数,变量等等。我们先来学习下反射要用到的api。拿User举例。
1 | // 获取User的reflectionClass对象 |
这时候我们可以创建一个make方法,传入User,利用反射机制拿到User的构造函数,进而得到构造函数的参数对象。用递归的方式创建参数依赖。最后调用newInstanceArgs方法生成User实例。下面我们用代码去简单模拟下。
1 | function make($concrete) |
具体代码实现
1 | // 注意我们这里需要修改一下User的构造函数 |
到这里,我们依赖注入,控制翻转,反射也就讲完了。