快速理解Laravel容器(IOC、DI、Provider、Contract)

这篇具有很好参考价值的文章主要介绍了快速理解Laravel容器(IOC、DI、Provider、Contract)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

源码理解思维的提升

分享一些个人见解。
Laravel里面的某些概念,就像魔术一样,看起来很厉害,当知道魔术怎么变的,就会认为也不过如此。所以不必感觉Laravel里有些概念难以理解。

应当抛除被框架约束思维的枷锁,用PHP设计的角度去思考,关注大概,而不是在在框架层面逐行磨叽。毕竟源码那么多,越是底层变量越多,越抽象,频繁的调用和变量指向,看到天亮也看不明白。

PHP设计的角度去思考怎么理解:
对于Laravel源码,代码很优雅,很工程化,很正规,方便扩展,这是优点,坏处就是抽象,好比垃圾桶里的垃圾都要摆放好,太过于工程化的设计,会给写松散业务逻辑的开发者带来困惑。
举个例子,Laravel里面的很多契约,好多都是一个空interface,放到了vendor下,真的是可要可不要,也确实有不少人说泰勒·奥特威尔就是炫技。
所以迟早要被绕晕,必须抛开Laravel里面的各种细节,用不需要太工程化PHP代码去尝试实现它,实现的过程中会遇到各种优化或者是问题,然后逐步优化。

被框架约束思维的枷锁怎么理解:
框架发展了这么久,源码的累加,不是让从头看的,而是遇到了一类问题,需要追加代码,是一个演进的过程,通过出现的问题或要优化的需求作为驱动来实现代码(书写顺序),而不是通过代码的作用反推解决的问题(反向反了很难看懂源码,看不懂干啥的,原因就是这里),换句话说,1+1=?是问题,2是结果。方向反了只有结果2,怎么推理出问题是1+1,还是2+0,既然不知道问题,又怎么知道2的意义是啥,那个地方要用?

易经思维:像各国人描述乌龟,得学很长时间的各国语言(源码),随手画一个乌龟(思维),全世界的人多能看懂。
要发掘的不是源码这样写我怎么看懂,而是这样写解决了什么问题。

通俗的演进示例

第1步:直接上第一版代码,Test类实现查询功能,于是调用了MySQL类的select方法。

class MySQL {
    public function select() {
        echo '执行查询操作';
    }
}


class Test {
    private $driver;
    public function __construct() {
        $this->driver = new MySQL();
    }

    public function search() {
        return $this->driver->select();
    }
}

$crud = new Test();
$crud->search();

第2步:但是如果以后有了Oracle,PostgreSQL怎么办?,代码内部的依赖写死了。
所以类的内部要写活,将内部的依赖,反转到外边,控制权由类的外部控制,通过构造方法传参实现,这就是控制反转,方便代码解耦。

<?php

class MySQL {
    public function select() {
        echo '执行查询操作';
    }
}


class Test {
    private $driver;
    public function __construct($driver) {
        $this->driver = $driver;
    }

    public function search() {
        return $this->driver->select();
    }
}

$crud = new Test(new MySQL);
$crud->search();

第3步:但是随着项目的复杂,类越来越多,对象到处都是,得有一个管事的领导人,进行统一管理,于是容器出现了。
容器至少需要两个方法,bind和make,bind用于存储,相当于领导人管辖的地域,分配一块地区,让这些容器有地方生存。make顾名思义就是制造,创建出来的这些容器(就是实例化的过程)让他们做事。
bind方法一般不会直接实例化对象,因为可能用不上,但是代码流程走到哪里了,存是得存起来,防止后期用得上,这很好理解,就好比Laravel的Cache模块,不是每次请求都一定能用得上,但是它仍旧会被预先加载。

class Container {
    private $container = [];

    public function bind($name, $class) {
        return $this->container[$name] = $class;
    }

    public function make($name) {
        $class = $this->container[$name] ?? null;
        if(! $class) {
            return null;
        }

        return new $class();
    }
}

第4步,整合到第2步的代码当中。
看起来简单东西搞复杂了,确实。但是框架中,对于大量的类和对象的管理却很有用,结合框架的反射,以及其它机制,是能够让类的管理变的更优雅的,
没有容器情况下的例子:
要狗肉账,张三问李四要债,李四说债务转移给王五了去问王五要,王五说债务转移给赵六了你去问他要,彼此踢皮球的环节耦合度太高,互相依赖。
快速理解Laravel容器(IOC、DI、Provider、Contract)

有容器情况下的例子:
相当于直接起诉到法院,一步到位,不管你是谁。我通过法院的管事人,去解决问题。
快速理解Laravel容器(IOC、DI、Provider、Contract)

<?php

class MySQL {
    public function select() {
        echo '执行查询操作';
    }
}


class Test {
    private $driver;
    public function __construct($driver) {
        $this->driver = $driver;
    }

    public function search() {
        return $this->driver->select();
    }
}


class Container {
    private $container = [];

    public function bind($name, $class) {
        return $this->container[$name] = $class;
    }

    public function make($name) {
        $class = $this->container[$name] ?? null;
        if(! $class) {
            return null;
        }

        return new $class();
    }
}

$container = new Container();
$container->bind('MySQL', MySQL::class);


$crud = new Test($container->make('MySQL'));
$crud->search();

Laravel容器

laravel容器的源码在vendor/laravel/framework/src/Illuminate/Container/Container.php
Laravel核心概念,类比成一个存放各类对象的数组,贯穿了整个Laravel流程,用于降低耦合度,管理并存储各模块的类与对象。
一个框架提供了很多模块,就需要很多对象,这些对象需要统一管理,自动实例化,以及类类型的形参自动实例化的反射机制,于是有了容器。

IOC(控制反转)

类内部的依赖,反转到类外边,控制权由类的外部控制,通过构造方法传参实现,这就是控制反转,方便代码解耦。
上文示例有说明。

DI(依赖注入)

依赖注入是控制反转的一种实现方式
依赖注入函数内部传参,有助于提高代码的模块化、可测试性和灵活性,通俗讲就是按(开发者)需加载。
如下,UserController依赖于UserService类。在控制器的构造函数中注入了 UserService,而不是在 UserController 中实例化UserService的实例。Laravel的服务容器的反射机制会自动解析这个依赖关系。

class UserController extends Controller {
    protected $userService;
    public function __construct(UserService $userService) {
        $this->userService = $userService;
    }
}

Contract(契约)

看了容器的源码,发现有用到,顺便提一嘴。
听起来高大上,移除Laravel框架高大上的思维枷锁,也就一堆接口,用于规范化代码,实现大体布局,子类用它实现细节,没什么神奇的高科技。

Provider(服务提供者)

多个服务提供者组成一个容器,新建的provider需要再config/app.php中声明。
用于注册应用程序的服务、绑定依赖关系以及其它初始化操作,真用到的时候就去实现,没那么严谨。
先调用register方法,然后会去调用boot方法。

这个在安装某些插件的时候回去用这个,composer包里的代码,不足以支撑当前的应用场景,所以需要做一些配置,然后就用到了Provider。

app()、resolve()

我看到前公司技术老大经常这样用,以我目前的认知来看,这和直接用命名空间的逻辑去调用一个类没什么区别。

  • app(); 返回服务容器实例,参数可传递类名,表示调用那个类。
  • resolve();app()的别名, 函数使用服务容器解析给定名称的类或接口的实例,参数可传递类名,表示调用那个类。

扩展阅读

浅谈PHP框架中类成员方法的类类型形参是怎么利用ReflectionClass反射类自动实例化的(应该是全网首发)文章来源地址https://www.toymoban.com/news/detail-855030.html

到了这里,关于快速理解Laravel容器(IOC、DI、Provider、Contract)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring核心容器IOC案例讲解,带你理解IOC

    Universe Infinity inc. 什么是IOC容器,先把IOC给忽略到,其实就是个容器。 什么?容器又是个啥玩意?容器是用来放东西的东西啊。 各个领域都喜欢起一些专业术语,显得很高级。给你讲IOC是不是很高级,给你讲Map是不是就明白了。 bean对象最终存储在spring容器中,在spring源码底

    2024年01月24日
    浏览(37)
  • 【框架源码】手写Spring框架IOC容器核心流程

    要是想要了解Spring IOC底层,首先我们就得先了解什么是IOC。 IOC就是控制反转,把对象创建和对象之间的调用过程交给Spring进行管理。 使用IOC目的就是之前我们创建对象的方式都是用new的方式创建,这个方式有个缺点,被创建对象的类的位置一旦被改动,new就会报错,类与类

    2024年02月06日
    浏览(51)
  • 深入分析Spring的IoC容器:从底层源码探索

    前言: 博主在最近的几次面试中,大中小厂都问到了Spring的ioc容器相关问题,这块知识确实是面试中的重点内容,因此结合所看的书籍,在这篇文章中总结下。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读,感谢大佬的关注。 如果文章有什么需要改进的地方欢迎

    2024年02月12日
    浏览(49)
  • Spring IoC&DI

    前面我们大概知道了什么是 Spring,以及 Spring 家族中 Spring Boot 和 Spring MVC的开发,但是 Spring 到底是什么呢? 前面我为大家简单介绍了什么是 Spring 【Spring】什么是Spring,不过前面的介绍较为简单,要想知道Spring 的原理,这些知识不不足以帮助我们了解 Spring 的,所以这篇文

    2024年02月04日
    浏览(45)
  • 【Spring源码解读一】IoC容器之AnnotationConfigApplicationContext

    AnnotationConfigApplicationContext构造方法 this() AnnotatedBeanDefinitionReader ClassPathBeanDefinitionScanner register(componentClasses)         根据AnnotationConfigApplicationContext类去阅读其将Bean对象交给IoC容器管理的过程。以下这三个代码块是将配置类注册进IoC容器的例子。下面是关于这个类的继承与

    2024年02月08日
    浏览(43)
  • 分层解耦、IOC和DI

    学习教程:【黑马程序员2023新版JavaWeb开发教程,实现javaweb企业开发全流程(涵盖Spring+MyBatis+SpringMVC+SpringBoot等)】 https://www.bilibili.com/video/BV1m84y1w7Tb/?p=161share_source=copy_webvd_source=2c07d62293f5003c919b2df9b2e0549e 在进行软件设计和软件开发时,需要让每个接口、类或方法的职责更加单

    2024年02月14日
    浏览(47)
  • Spring IoC&DI(2)

    通过上面的案例, 我们已经知道了IoC和DI的基本操作, 接下来我们来系统地学习Spring IoC和DI的操作. 前面我们提到的IoC控制反转, 就是将对象的控制权交给Spring的IoC容器, 由IoC容器创建及管理对象.  ( 也就是Bean的存储 ). 我们之前只讲到了@Component注解来使得对象交给IoC容器管理

    2024年04月10日
    浏览(47)
  • 【学习】Spring IoC&DI

    🎥 个人主页:Dikz12 📕格言:吾愚多不敏,而愿加学 欢迎大家👍点赞✍评论⭐收藏 目录 Spring 是什么? 什么是 IoC容器? 传统开发模式  loC开发模式 IoC的优势  IoC 的使用 Bean的存储   方法注解  DI  属性注入  构造⽅法注⼊  Setter 注⼊ @Autowired存在的问题  解决方案:

    2024年04月15日
    浏览(49)
  • 什么是IoC?什么是Spring IoC?什么是DI?

    首先说明 IoC 是一种思想,IoC的全称是Inversion of Control,翻译成中文叫做 “控制反转” 用人话来说,IoC的思想就是将一个对象对另一个对象的控制权交出去(不必关心交给谁),从而让对象之间的依赖关系降低,降低代码之间耦合程度。 我们可以写一个简单的代码来举个例子

    2024年02月14日
    浏览(49)
  • .net core di ioc

    (Dependency Injection,DI)依赖注入,又称依赖关系注入,是一种软件设计模式,也是依赖倒置原则的一种体现。 依赖倒置原则的含义如下 上层模块不依赖下层模块。二者都依赖抽象 抽象不依赖细节 细节依赖抽象 依赖注入原则有别于传统的通过new直接依赖下层模块的形式,

    2024年02月22日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包