欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Laravel源码分析之Contracts契约

程序员文章站 2022-06-15 17:22:38
...
  • 何为契约?契约其实就是面向接口编程,一个类不依赖于具体实现类,而是依赖于其接口。

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

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时,我们仅仅需要从外部传入各自的实例对象,而不必修改内部代码。