学习记录-Laravel 核心 依赖注入 控制反转 反射
控制反转 依赖注入理解
interface DbConnect {
public function connect();
}
class DbA implements DbConnect {
public function connect()
{
// TODO: Implement test_echo() method.
echo 'A';
}
}
class DbB implements DbConnect {
public function connect()
{
// TODO: Implement test_echo() method.
echo "B";
}
}
class ConnectDb {
protected $connects;
public function __construct()
{
$this->connect = new DbA();
}
public function connect()
{
echo $this->connect->connect();
}
}
上面写法可以实现数据库连接功能,但是要切换到B数据库就要修改ConnectDb类,这样代码没法达到低耦合,也不符合编程开放封闭原则。我们可以把连接的类用函数传参的方式传进ConnectDb构造函数里.
class ConnectDb {
protected $connects;
public function __construct(DbConnect $dbConnect)
{
$this->connect = $dbConnect;
}
public function connect()
{
echo $this->connect->connect();
}
}
$ConnectDb = new ConnectDb(new DbA());
$ConnectDb->connect();
这样我们就可以不修改ConnectDb而是用构造函数参数传递的方式切换数据库,这就是控制反转(感觉好像工厂模式。。。),不需要自己内容修改,通过外部传递参数,这种由外部负责其依赖需求的行为,称控制反转(IoC)
不通过自己内部new 对象或者实例,而是通过函数或者构造函数传递进来。称为依赖注入(DI)
反射
刚毕业那会面试一家公司面试就问我了不了解反射,当时给我问的一懵。工作这么长时间了其实还是不了解。。。。
反射其实就是根据类名返回这个类的任何信息,比如该类的方法,参数,属性等等
ReflectionClass 类报告了一个类的有关信息。
// — 初始化 ReflectionClass 类
$reflectionClass = new ReflectionClass('ConnectDb');
// — 获取类的构造函数 一个 ReflectionMethod 对象,反射了类的构造函数,或者当类不存在构造函数时返回 NULL。
$constructor = $reflectionClass->getConstructor();
// - 获取构造函数所有依赖参数
$dependencies = $constructor->getParameters();
// - 创建类的新的实例。给出的参数将会传递到类的构造函数。
$ConnectDb = $reflectionClass->newInstance();
// - 创建一个类的新实例,给出的参数将传递到类的构造函数。这个参数以 array 形式传递到类的构造函数 返回值 返回类的实例
$ConnectDb = $reflectionClass->newInstanceArgs($dependencies);
我们可以创建一个方法,利用反射的机制拿到ConnectDb类的构造函数,然后拿到构造函数的参数对象,用递归的方法创建参数依赖,最后调用newInstanceArgs方法生成ConnectDb实例
interface DbConnect {
public function connect();
}
class DbA implements DbConnect {
public function connect()
{
// TODO: Implement test_echo() method.
echo 'A';
}
}
class DbB implements DbConnect {
public function connect()
{
// TODO: Implement test_echo() method.
echo "B";
}
}
class ConnectDb {
protected $connects;
//反射是不能动态创建接口的
public function __construct(DbA $dbConnect)
{
$this->connect = $dbConnect;
}
public function connect()
{
echo $this->connect->connect();
}
}
function make ($concrete) {
// — 初始化 ReflectionClass 类
$reflectionClass = new ReflectionClass($concrete);
// — 获取类的构造函数 一个 ReflectionMethod 对象,反射了类的构造函数,或者当类不存在构造函数时返回 NULL。
$constructor = $reflectionClass->getConstructor();
//如果不需要传递参数直接返回实例
if (is_null($constructor)) {
return $reflectionClass->newInstance();
} else {
// - 获取构造函数所有依赖参数
$dependencies = $constructor->getParameters();
$instance = getdependencies($dependencies);
return $reflectionClass->newInstanceArgs($instance);
}
}
function getdependencies($parameter)
{
$dependencies = [];
foreach ($parameter as $paramete) {
//返回对象实例 object 所属类的名字。返回对象实例 object 所属类的名字。 如果 object 不是一个对象则返回 FALSE。
$dependencies[] = make($paramete->getClass()->name);
}
return $dependencies;
}
$ConnectDb = make('ConnectDb');
$ConnectDb->connect();
总结:
- 控制反转(IoC):不修改类内部自身,通过外部参数传递的方式,由外部负责其依赖需求的行为。
- 依赖注入(DI) :不通过自己new 或实例实例化,通过函数或者构造函数传递进来。
- 反射:根据类名获取类的信息,方法、属性、参数等等
文章借鉴,也不算借鉴了。抄了深入laravel核心有兴趣的可以去看一下,也是自己做个记录。
本作品采用《CC 协议》,转载必须注明作者和本文链接
这个没有注入interface,改成dbb还有改构造函数,应该有bind,将db绑定到a或者b