快速入门Laravel核心概念

想要熟练的使用laravel就必须要理解它的核心概念。

Ioc容器

IoC的全称是Inversion of Control(控制反转),它是一种设计模式。它旨在解耦和管理软件组件之间的依赖关系,从而提高代码的可维护性和可测试性。

DI的全称是Dependency Injection(依赖注入),是实现IoC的一种方式。


// 日志类
class FileLogger {
    public function log($message) {
        echo "Logging message to file: $message\\n";
    }
}

// 用户类(业务逻辑)
class User {
    protected $logger;

    public function __construct() {
        $this->logger = new FileLogger();
    }

    // 一个简单的方法,记录用户行为
    public function createUser($username) {
        echo "User created: $username\\n";
        $this->logger->log("User created: $username");
    }
}

// 应用程序入口
$user = new User();
// 创建一个用户,会自动记录日志
$user->createUser("John Doe");

上面定义了一个名为FileLogger的日志类,和一个具有创建用户功能的User类,User类在创建用户的时候需要记录日志。记录日志的功能由专门的日志类FileLogger来实现。

User需要记录日志的功能,因此在User构造函数中创建了FileLogger。这样做的问题在一User和FileLogger绑定在一起,如果FileLogger的不能满足User调用方的需求,那么调用方得重新创建一个User的子类,然后在子类的构造函数中创建自己的日志对象。

class MemoryLogger {
    public function log($message) {
        echo "Logging message to file: $message\\n";
    }
}

class MyUser extends User{
       public function __construct() {
        $this->logger = new MemoryLogger();
    }
}

这种方式让组件之间的依赖度太高。不利于代码维护和测试。

才有IoC的方式实现上面的功能。


// 依赖注入的接口
interface Logger {
    public function log($message);
}

// 实现了依赖注入接口的文件日志类
class FileLogger implements Logger {
    public function log($message) {
        echo "Logging message to file: $message\\n";
    }
}

class MemoryLogger implements Logger{
    public function log($message) {
        echo "Logging message to file: $message\\n";
    }
}

// 用户类,它依赖于 Logger 接口
class User {
    protected $logger;

    // 通过构造函数注入依赖
    // 依赖的是接口,不是具体的实现,因此可以按需替换,无法改变User内部的代码
    public function __construct(Logger $logger) {
        $this->logger = $logger;
    }

    // 一个简单的方法,记录用户行为
    public function createUser($username) {
        echo "User created: $username\\n";
        $this->logger->log("User created: $username");
    }
}

// 应用程序入口
// 在这里我们控制了依赖注入,根据需要注入不同的 Logger 实现
$logger = new FileLogger();
$user = new User($logger);
// 创建一个用户,会自动记录日志
$user->createUser("John Doe");

// 如果需要使用MemoryLogger,构建相应的对象传入,不用修改User内部的实现
$logger = new MemoryLogger();
$user = new User($logger);
$user->createUser("John Doe");

与未使用IoC的方式相比有几个变化:

  • User不在内部去创建日志对象,而是通过定义函数参数的方式传入。
  • User不依赖某个具体的日志类型,而且依赖Logger接口。这种面相接口编程方式不仅可以提高代码的可维护性,还可以更方便的写测试。

这样在User和Logger组件之间就实现了解耦。

Service Provider服务提供者

Laravel的功能都是通过service provider的形式提供。 service Provider本身不提供具体服务的业务实现,而是把服务注册到IoC容器。例如LoggerServiceProvider把日志服务注册到IoC容器中,让容器有日志功能。

所有的service provider都是继承ServiceProvider。ServiceProvider通过2个方式定义了service provider的生命周期:

  • register方法,注册服务,告诉IoC容器如何创建服务。
  • boot方法,初始化服务,IoC创建服务之后执行一些初始化的操作

下面的例子提供了一个生成随机数的服务

<?php

namespace App\\Providers;

use Illuminate\\Support\\ServiceProvider;

// 生成随机数
class RandomStringGenerator{

}

class RandomStringServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        // 将 RandomStringGenerator 绑定到容器
        $this->app->bind('randomString', function ($app) {
            return new RandomStringGenerator();
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        // 执行初始化操作,这个时候可以访问到IoC容器注册的其它服务了
    }
}

上面的例子中可以发现,RandomStringServiceProvider本身并不提供生成随机数的功能,它只是把

RandomStringGenerator注册到了IoC容器里面,具体的生成随机数的功能是由RandomStringGenerator实现。

Middleware 中间件

中间件提供了一种在http请求被处理之前和之后能执行一段额外的逻辑。在很多web框架中都有这个概念。

下面这张流程图很好的解释了中间件的用途

快速入门Laravel核心概念

Facade门脸模式

Facede需要和service provider结合使用。它主要的作用是简化service provider提供服务的API使用。

例如Laravel通过CacheServiceProvider提供了缓存的功能,具体的实现是由CacheManager这个类来实现的。定义如下:

 public function register()
    {
        $this->app->singleton('cache', function ($app) {
            return new CacheManager($app);
        });

       // ... 其它代码省略
    }

在不用Facade的前提下需要这样使用CacheManager上的方法app(’cache’)→xxxx()。

如果利用Facade模式则可以这样使用Cache::xxxxx()。它的底层实现原理是利用了class_alias和__callStatic模式方法。

Laravel的Facede模式不仅可以简化API使用,它还提供了mock服务的功能,可以方便写测试。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

好好学习天天向上~

2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!