Laravel源码分析之Contracts契约

不打扰是莪最后的温柔 提交于 2020-03-07 02:53:18
  • 何为契约?契约其实就是面向接口编程,一个类不依赖于具体实现类,而是依赖于其接口。

  • 首先看Laravel源中有一个Contracts目录,该目录下所有文件除了异常定义以外,其余均是接口定义。

在这里插入图片描述
通过定义好接口,具体实现类则可以依赖于接口,只要实现了接口的类都可以成为被依赖对象。

  • 举个例子: 比如需要对内容进行缓存,可以使用文件缓存丶Redis缓存等。

    • 先看不使用接口的代码有什么问题。
    <?php
    
    
    /**
     * 文件缓存
     */
    class FileCache
    {
        public function cache($val)
        {
            echo 'Using File Cache: ' . $val;
        }
    }
    
    /**
     * Redis缓存
     */
    class RedisCache
    {
        public function cache($val)
        {
            echo 'Using Redis Cache: ' . $val;
        }
    }
    
    class Article
    {
        protected $cache;
    
        public function __construct(FileCache $cache)
        {
            $this->cache = $cache;
        }
    
        public function getArticles()
        {
            $content = 'Hello World!';
            $this->cache->cache($content);
        }
    }
    
    $art = new Article(new FileCache());
    $art->getArticles();
    

    定义了两个缓存具体实现类分别是RedisCacheFileCacheArticle类依赖的是具体实现类FileCache,那么在需要修改缓存为RedisCache时,我们不得不去修改Article类的构造方法注入RedisCache,然后调用的时候传入RedisCache的实例,所以这段代码的还是不理想的。

    • 使用面向接口编程:
<?php

/**
 * 缓存接口
 */
interface Cache
{
    public function cache($val);
}

/**
 * 文件缓存
 */
class FileCache implements Cache
{
    public function cache($val)
    {
        echo 'Using File Cache: ' . $val . PHP_EOL;
    }
}

/**
 * Redis缓存
 */
class RedisCache implements Cache
{
    public function cache($val)
    {
        echo 'Using Redis Cache: ' . $val . PHP_EOL;
    }
}

class Article
{
    protected $cache;

    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }

    public function getArticles()
    {
        $content = 'Hello World!' . PHP_EOL;
        $this->cache->cache($content);
    }
}

$art = new Article(new FileCache());
$art->getArticles();
$art2 = new Article(new RedisCache());
$art2->getArticles();

此处新定义了一个接口,RedisCacheFileCache分别实现了Cache接口,在Article类中注入的依赖是接口Cache, 所以在切换FileCacheRedisCache时,我们仅仅需要从外部传入各自的实例对象,而不必修改内部代码。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!