-
何为契约?契约其实就是面向接口编程,一个类不依赖于具体实现类,而是依赖于其接口。
-
首先看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();
定义了两个缓存具体实现类分别是
RedisCache
和FileCache
,Article
类依赖的是具体实现类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();
此处新定义了一个接口,RedisCache
和FileCache
分别实现了Cache
接口,在Article
类中注入的依赖是接口Cache
, 所以在切换FileCache
和RedisCache
时,我们仅仅需要从外部传入各自的实例对象,而不必修改内部代码。
来源:CSDN
作者:ClassmateLin
链接:https://blog.csdn.net/ClassmateLin/article/details/104698820