【Laravel5.2翻译】Contacts


前阵子看了点Laravel源码,越看越乱,网上大部分中文文档都是直译,比较生涩难懂,还是决定看英文文档顺便就我的理解做下翻译整理记录下来

思维导图

简介

Larvel的Contracts是一系列接口,它们定义了由框架提供的核心服务。例如,Illuminate\Contracts\Queue\Queue定义了队列工作需要的方法,Illuminate\Contracts\Mail\Mailer定义了发送邮件的方法。
每个contract都有框架提供的对应实现。例如,Laravel提供了不同驱动下的queue实现,还有一个SwiftMailer的mailer实现

所有的Laravel contracts都存放在他们自己的GitHub仓库中。这提供了一个快速导航,可以让你定位到可用的contracts,还有独立的,解耦的package让package开发者可以用来开发。

Contracts和门面

Laravel的门面提供了一个利用Laravel服务的简洁方法,不需要类型提示也不需要从服务容器中解析contracts。然而,用contracts可以为一个类定义明确的依赖。对于大多数应用,门面很好用。当然,如果你需要contracts提供的极度松耦合,那就读下去!

为什么要用Contracts

你可能有很多关于contracts的问题。为什么要用接口?用接口会不会更复杂?让我们从下面几点来挖掘用接口的理由:松耦合和简洁。

松耦合

首先,让我们回顾一段缓存首先紧耦合的代码:

<?php

namespace App\Orders;

class Repository
{
    /**
     * The cache instance.
     */
    protected $cache;

    /**
     * Create a new repository instance.
     *
     * @param  \SomePackage\Cache\Memcached  $cache
     * @return void
     */
    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }

    /**
     * Retrieve an Order by ID.
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}

在这个类中,代码对指定缓存实现紧耦合。这是一个紧耦合因为我们依赖于vendor包内的固定的缓存。如果那个package内的API发生的变化,我们的代码也要变。
同样的,如果我们想要把底层缓存技术(Mecached)替换成另一个技术(Redis),我们必须修改仓库。我们的仓库无法得知谁提供了数据还有他们如何提供。

取而代之,我们可以改进我们的代码,让它们依赖于一个简单的,vendor无关的接口:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository
{
    /**
     * The cache instance.
     */
    protected $cache;

    /**
     * Create a new repository instance.
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }
}

现在代码不耦合于任何特定的vendor或者Laravel。因为contracts不包含任何实现和依赖,可以轻松为contract编写可变实现,你可以替换缓存实现而不用修改任何它服务的代码

简洁

当所有的Laravel服务都由简单接口定义,明确给定服务提供的功能就会变得简单。contracts就像框架特征的一个简洁文档
另外,当依赖简单的接口,你的代码理解和维护起来就更简单。不用再从庞大,复杂的类中查看哪个方法可以用,你只要参考简单干净的接口就可以了。

如何使用Contracts

你如何获得一个contract实现?这很简单。
很多类型的类都是通过服务器容器解析的,包括控制器、事件监听、中间件、队列工作甚至路由闭包。所以,你只需要在要解析的类的构造函数中类型提示接就可以获得contract的实现了。

例如,看看下面这个事件监听:

<?php

namespace App\Listeners;

use App\User;
use App\Events\NewUserRegistered;
use Illuminate\Contracts\Redis\Database;

class CacheUserInformation
{
    /**
     * The Redis database implementation.
     */
    protected $redis;

    /**
     * Create a new event handler instance.
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * Handle the event.
     *
     * @param  NewUserRegistered  $event
     * @return void
     */
    public function handle(NewUserRegistered $event)
    {
        //
    }
}

当你的事件监听被解析,服务容器会读取构造函数类型提示,然后注入适当的值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,253评论 19 139
  • 先说几句废话,调和气氛。事情的起由来自客户需求频繁变更,伟大的师傅决定横刀立马的改革使用新的框架(created ...
    wsdadan阅读 3,124评论 0 12
  • 原文链接 必备品 文档:Documentation API:API Reference 视频:Laracasts ...
    layjoy阅读 8,650评论 0 121
  • 过去做事情急,什么东西拿起来就用,不喜欢进行系统性的学习,造成在使用过程中的错误和低效,现在感觉自己耐心多了,用之...
    马文Marvin阅读 2,052评论 0 10
  • 今天开始准备写作业,云吞:一斤虾,4两肉,一斤虾一汤匙芝麻粉,一汤匙大地鱼粉,白芝麻炸了,凉好装瓶里,需要时打磨成...
    慧蘭阅读 180评论 0 0