浅谈 Laravel 设计模式

Hello!我是Shelter。最近刚开始学Laravel,研究了一阵子,和大家分享个人的理解。

我想很多刚开始学Laravel的都会为Laravel的设计模式感到头疼。毕竟文档侧重点大都是应用,前面的底层设计模式讲得比较模糊。笔者也是断断续续看了一阵子,才理清了思路,在这里和大家分享下!

一.什么是 DI依赖注入/IOC控制反转.

DI依赖注入

啥都不说,直接上代码

<?php
    class UserController 
    {
        private $user;

        function __construct(UserModel $user) {
            $this->user = $user;
        }
    }

    $user = new UserController(new UserMonel());
?>

User控制器依赖UserModel,实例化的时候,直接注入。

IOC控制反转

先说IOC和DI的区别吧!

  • IOC是一种设计思想
  • DI是一种设计模式

所以两者有本质上的区别。DI是IOC的一种实现方法(还有ServiceLocator等其他设计模式)。
所谓的反转,主要指由 主动依赖被动依赖

    //主动依赖
    function __construct() {
            $this->user = new UserModel();
    }

    //被动依赖
    function __construct(UserModel $user) {
            $this->user = $user;
    }

参考 浅谈IOC--说清楚IOC是什么

二.什么是IOC容器.

IOC容器 是Laravel的核心设计模式,对于laravel的应用和理解是非常有必要深入学习的!

IOC思想实现了高度解耦,那么,问题来了,如何管理这些分散的模块呢?这就是容器的任务了!

可以想象成,在IOC容器中,装着(注册)很多模块。当用户需要一个模块的时候,可以从中拿出来。当提取的模块依赖另一个模块的时候,容器会自动注入,再返回给用户(反射机制实现)。

是不是碉堡了?大批互相依赖的模块被完美解耦并统一管理了!

三.什么是服务提供者(ServiceProvider).

假设模块一多,那么容器不是越来越大?每次加载,岂不是加载好久?
能不能弄一条管子,连接着模块,插在容器上,需要再通过管道获取呢?这样子,容器只是装着管头而已,就不怕被撑大了!

这条管子就是 服务提供者

file

服务提供者本身也是一个类,不过这个类只有启动和注册两个函数。

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
       //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //绑定到容器
        $this->app->singleton(
            'Riak\Contracts\Connection', 
            function ($app) {
                return new Connection($app['config']['riak']);
            }
        );
    }

服务提供者在config/app.php中配置,laravel自动注册到容器中。

    'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        ...

        /*
         * Application Service Providers...
         */
        app\Providers\AppServiceProvider::class,
        app\Providers\AuthServiceProvider::class,
        ...
    ]

四.什么是门面(Facade).

程序猿总是偷懒的,每次要模块,都要去容器里面拿,多麻烦啊!找个人代拿行不?这送货小哥就叫Facade门面。文档中叫静态代理。

送货小哥都是在config/app.php 中注册的。

    'aliases' => [
        'App'       => Illuminate\Support\Facades\App::class,
        'Config'    => Illuminate\Support\Facades\Config::class,
        'Cookie'    => Illuminate\Support\Facades\Cookie::class,
        'Crypt'     => Illuminate\Support\Facades\Crypt::class,
        'DB'        => Illuminate\Support\Facades\DB::class,
        'Route'     => Illuminate\Support\Facades\Route::class,
        ...
    ],

查看Illuminate\Support\Facades\Route代码,可以发现只有getAccessFacade()方法,这就是交代送啥货的函数,继承了Facade这个小哥基类。

    class Route extends Facade
    {
        /**
         * Get the registered name of the component.
         *
         * @return string
         */
        protected static function getFacadeAccessor()
        {
            return 'router';
        }
    }

注册了Facade门面后,就可以在任意地方使用了!

文档有详细的使用方式 Laravel 架构 — Facades

五.Application和Kernel

不难发现,在引导程序开始初始化的时候,也就是在boostrap\app.php文件,里面一来就new了一个 Illuminate\Foundation\Application。下面分别注册了 Http\Kernel、Console\Kernel、Exceptions\Handler等。

这里可以这么理解,new一个Application,可以看作是创造了一个空间,这个空间初始化的时候,就会为自己注入一个容器,也就是在空间中放了一个容器。

Illuminate\Foundation\Application.php 中的 registerBaseBindings() 函数可以查看到容器注入源码。

至于kernel,可以看成是这个空间的工人,有各种各样的工人,每个工人都有自己的工作。好比HttpKernel,负责处理http请求以及控制整个请求流程。

六.总结

讲到这里就差不多分享完了,以上是只是个人理解,欢迎提出里面理解不妥当的地方!

认真,可以让事情变得出乎意料地好!

本帖已被设为精华帖!
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 20
hareluya

好文,当年学习的时候没找到整理这么清晰的文章。

3年前

@MonsterOOF 新建一个迁移文件,这个迁移文件主要负责增加字段,最后执行迁移文件。

2年前

我也是刚接触 确实对laravel设计模式比较迷糊
感谢作者分享

9个月前

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

社区文档:

将托管在 packagist.org 和 github.com 的扩展包使用国内 CDN 加速
GitHub Laravel 扩展包 TOP 250
速查表方便快速查询框架功能,支持手机访问,支持中英文版本
Laravel 中文文档,由社区用户翻译和维护,将会保持一直更新
此文档的目的,就是为了提高技术团队的凝聚力、一致性和生产效率。
开发环境的部署,开发者工具的选择,适用于 Mac 和 Windows。
Laravel Nova 后台管理面板文档的中文翻译
Lumen 中文文档,由社区用户翻译和维护,将会保持一直更新
Laravel 下知名扩展包 Dingo API 的中文文档,Laravel API 开发必知必会