DIY 实现 ThinkPHP 核心框架(八)控制反转和依赖注入
软件工程提倡高内聚、低耦合,控制反转是一种有效的设计原则,而依赖注入是控制反转的一种实现方式。有以下代码
class Demo
{
public function show()
{
$test = new Test();
}
}
如果不实例化 Test
类, Demo
类也就没有意义。但是这种关系会增加代码的耦合性,如果 Test
类实例化方式改变, Demo
代码也要随之更改。如果类似的情况很多,项目代码会显得凌乱。
为解决这个问题, ThinkPHP 提供了一个容器类 Container
, 创建 Test
实例的任务交由 Container
类 完成,将 Test
实例作为参数传给 Demo
类的 show()
方法。
将创建实例的控制权交给 Container
类实现控制反转,而 show()
方法依赖的 Test 类通过参数从外部传入实现依赖注入。
class Demo
{
public function show(Test $test)
{}
}
创建 core/src/think/Container.php
文件
namespace think;
//use ReflectionClass;
//use ReflectionFunctionAbstract;
/**
* 以下属性、方法的代码 ThinkPHP 5 与 6 中基本保持一致
* 采用“拿来主义”
* Class Container
* @package think
*/
class Container
{
protected $instances = [];
public function make (string $class)
{
$class = '\\think\\' . $class;
if (!isset($this->instances[$class])) {
$this->instances[$class] = new $class();
}
return $this->instances[$class];
}
public function show()
{
$request = $this->make('Request');
$index = new \app\index\controller\Index();
$index->show($request);
}
}
创建 core/src/think/Request.php
文件
namespace think;
class Request
{}
修改 application/index/controller/Index.php
, 引入 Request
类的命名空间,编写 show()
方法接受 Request
类的实例参数 $req 。
namespace app\index\controller;
use think\Request;
class Index
{
public function show (Request $req)
{
var_dump($req instanceof Request);
}
}
修改入口文件 public/index.php
进行测试
require __DIR__ . '/../core/base.php';
(new \think\Container)->show();
访问 diy.tp ,运行结果为 bool(true) 说明成功实现依赖注入。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: